﻿using JNPF.Utils.Extensions;
using JNPF.Utils.Models.CodeBuilder;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;

namespace JNPF.Utils
{
    /// <summary>
    /// 代码生成器
    /// 版 本：V3.0.0
    /// 版 权：引迈信息技术有限公司（https://www.jnpfsoft.com）
    /// 作 者：JNPF开发平台组
    /// <remarks>根据指定的实体域名空间生成Repositories和Services层的基础代码文件</remarks>
    /// </summary>
    public class CodeGenerator
    {
        private string Delimiter = @"/";//分隔符，默认为windows下的\\分隔符
        public CodeGenerateOption Option { get; set; }
        /// <summary>
        /// 静态构造函数：从IoC容器读取配置参数，如果读取失败则会抛出ArgumentNullException异常
        /// </summary>
        public CodeGenerator(CodeGenerateOption option)
        {
            Option = option;
            var path = AppDomain.CurrentDomain.BaseDirectory;
            var flag = path.IndexOf("/bin");
            if (flag > 0)
                Delimiter = "/";//如果可以取到值，修改分割符
        }

        /// <summary>
        /// 从代码模板中读取内容
        /// </summary>
        /// <param name="templateName">模板名称，应包括文件扩展名称。比如：template.txt</param>
        /// <returns></returns>
        public string ReadTemplate(string templateName)
        {
            var currentAssembly = Assembly.GetExecutingAssembly();
            var content = string.Empty;
            using (var stream = currentAssembly.GetManifestResourceStream($"{currentAssembly.GetName().Name}.CodeTemplate.{templateName}"))
            {
                if (stream != null)
                {
                    using (var reader = new StreamReader(stream))
                    {
                        content = reader.ReadToEnd();
                    }
                }
            }
            return content;
        }


        /// <summary>
        /// 生成前端列表页
        /// </summary>
        /// <param name="modelTypeName"></param>
        /// <param name="ajaxUrl"></param>
        /// <param name="searchBar"></param>
        /// <param name="searchFolding"></param>
        /// <param name="btnList"></param>
        /// <param name="columnList"></param>
        /// <param name="columnBtnsList"></param>
        /// <param name="hasPage"></param>
        /// <param name="queryParameter"></param>
        /// <param name="hasPageParameter"></param>
        /// <param name="dataColumnList"></param>
        /// <param name="dataCreated"></param>
        /// <param name="dictionaryDataMethods"></param>
        /// <param name="formDataOptions"></param>
        public void GenerateVueIndex(string modelTypeName, string ajaxUrl, string indexPage, string queryParameter, string hasPageParameter, string dataColumnList, string dataCreated, string dictionaryDataMethods, string formDataOptions, string treeParameter, string formCreated, string formTreeMethods)
        {
            var repositoryPath = Option.OutputPath + Delimiter + "vue/" + modelTypeName;
            if (!Directory.Exists(repositoryPath))
            {
                Directory.CreateDirectory(repositoryPath);
            }
            var fullPath = repositoryPath + Delimiter + "index.vue";
            var content = ReadTemplate("IndexTemplate.txt");
            content = content.Replace("{IndexPage}", indexPage)
                .Replace("{TreeParameter}", treeParameter)
                .Replace("{FormCreated}", formCreated)
                .Replace("{FormTreeMethods}", formTreeMethods)
                .Replace("{QueryParameter}", queryParameter)
                .Replace("{HasPageParameter}", hasPageParameter)
                .Replace("{DataColumnList}", dataColumnList)
                .Replace("{FormDataCreated}", dataCreated)
                .Replace("{FormDataMethods}", dictionaryDataMethods)
                .Replace("{FormDataOptions}", formDataOptions)
                .Replace("{AjaxUrl}", ajaxUrl);
            WriteAndSave(fullPath, content);
        }

        /// <summary>
        /// 生成功能表单Form页面
        /// </summary>
        /// <param name="modelTypeName"></param>
        /// <param name="columnPrimary"></param>
        /// <param name="ajaxUrl"></param>
        /// <param name="formControls"></param>
        /// <param name="formDataParameter"></param>
        /// <param name="formDataOptions"></param>
        /// <param name="dataInitMethods"></param>
        /// <param name="formTableColumn"></param>
        /// <param name="dataCreated"></param>
        /// <param name="dataMethods"></param>
        /// <param name="formValidation"></param>
        public void GenerateVueForm(string modelTypeName, string columnPrimary, string ajaxUrl, string formControls, string formDataParameter, string formDataOptions, string dataInitMethods, string dataListInitMethods, string formTableColumn, string dataCreated, string dataMethods, string formValidation, string formFileData, string dataListFormSubmit)
        {
            var repositoryPath = Option.OutputPath + Delimiter + "vue/" + modelTypeName;
            if (!Directory.Exists(repositoryPath))
            {
                Directory.CreateDirectory(repositoryPath);
            }
            var fullPath = repositoryPath + Delimiter + "Form.vue";
            var content = ReadTemplate("FormTemplate.txt");
            content = content.Replace("{FormControls}", formControls)
                .Replace("{FormDataParameter}", formDataParameter)
                .Replace("{FormDataOptions}", formDataOptions)
                .Replace("{DataInitMethods}", dataInitMethods)
                .Replace("{DataListInitMethods}", dataListInitMethods)
                .Replace("{FormTableColumn}", formTableColumn)
                .Replace("{FormDataCreated}", dataCreated)
                .Replace("{FormDataMethods}", dataMethods)
                .Replace("{FormValidation}", formValidation)
                .Replace("{FormFileData}", formFileData)
                .Replace("{DataListFormSubmit}", dataListFormSubmit)
                .Replace("{AjaxUrl}", ajaxUrl)
                .Replace("{ColumnPrimary}", columnPrimary.ToLower());
            WriteAndSave(fullPath, content);
        }

        public void GenerateVueExportBox(string modelTypeName)
        {
            var repositoryPath = Option.OutputPath + Delimiter + "vue/" + modelTypeName;
            if (!Directory.Exists(repositoryPath))
            {
                Directory.CreateDirectory(repositoryPath);
            }
            var fullPath = repositoryPath + Delimiter + "ExportBox.vue";
            var content = ReadTemplate("ExportBoxTemplate.txt");
            WriteAndSave(fullPath, content);
        }

        /// <summary>
        /// 生成实体类
        /// </summary>
        /// <param name="table">数据源</param>
        /// <param name="ifExistCovered">是否覆盖文件</param>
        public void GenerateEntity(DbTable table, bool ifExistCovered = false)
        {
            var modelPath = Option.OutputPath + Delimiter + "Models/Entity";
            if (!Directory.Exists(modelPath))
            {
                Directory.CreateDirectory(modelPath);
            }

            var tableName = table.Alias;
            var className = table.Alias.IsNullOrEmpty() ? tableName : table.Alias;

            var fullPath = modelPath + Delimiter + tableName + "Entity.cs";
            if (File.Exists(fullPath) && !ifExistCovered)
                return;

            var pkTypeName = table.Columns.First(m => m.IsPrimaryKey).CSharpType;
            var sb = new StringBuilder();
            foreach (var column in table.Columns)
            {
                var tmp = GenerateEntityProperty(column);
                sb.AppendLine(tmp);
            }
            var content = ReadTemplate("EntityTemplate.txt");
            content = content.Replace("{ModelsNamespace}", Option.EntityNamespace)
                .Replace("{Comment}", table.TableComment)
                .Replace("{TableName}", table.TableName.ToUpper())
                .Replace("{ModelName}", className)
                .Replace("{KeyTypeName}", pkTypeName)
                .Replace("{ModelProperties}", sb.ToString());
            WriteAndSave(fullPath, content);
        }

        /// <summary>
        /// 生成输入实体类
        /// </summary>
        /// <param name="table">数据源</param>
        /// <param name="fileName">文件名称</param>
        /// <param name="childTable">子表名称列表</param>
        /// <param name="isListQuery">是否为列表查询</param>
        /// <param name="ifExistCovered">是否覆盖文件</param>
        public void GenerateModelEntity(DbTable table, string fileName, List<string> childTable, List<string> fixedFieldList, List<GeneratorFormColumn> formColumn, bool isListQuery, bool ifExistCovered = false)
        {
            var modelPath = Option.OutputPath + Delimiter + "Models/Dtos";
            if (!Directory.Exists(modelPath))
            {
                Directory.CreateDirectory(modelPath);
            }

            var tableName = table.Alias;
            var className = table.Alias.IsNullOrEmpty() ? tableName : table.Alias;

            var fullPath = modelPath + Delimiter + fileName + ".cs";
            if (File.Exists(fullPath) && !ifExistCovered)
                return;

            var sb = new StringBuilder();
            foreach (var column in table.Columns)
            {
                var tmp = GenerateModelsProperty(column, formColumn, fileName);
                sb.AppendLine(tmp);
            }
            if (childTable != null)
            {
                childTable.ForEach(c =>
                {
                    var name = string.Empty;
                    switch (fileName.Replace(table.Alias, ""))
                    {
                        case "ListOutput":
                            name = "Entity";
                            break;
                        default:
                            name = fileName.Replace(table.Alias, "");
                            break;
                    }
                    sb.AppendLine($"\t\tpublic List<{c + name}> {c} " + "{get;set;}");
                    sb.AppendLine();
                });
            }
            if (fixedFieldList != null)
            {
                fixedFieldList.ForEach(c =>
                {
                    if (c == "actionType" || c == "status")
                    {
                        sb.AppendLine($"\t\tpublic int {c} " + "{get;set;}");
                    }
                    else
                    {
                        sb.AppendLine($"\t\tpublic string {c} " + "{get;set;}");
                    }
                    sb.AppendLine();
                });
            }
            if (fileName.IndexOf("ListQueryInput") > 0)
            {
                sb.AppendLine("\t\tpublic int dataType { get; set; }");
                sb.AppendLine();
                sb.AppendLine("\t\tpublic string selectKey { get; set; }");
            }
            var content = ReadTemplate("ModelTemplate.txt");
            content = content.Replace("{ModelsNamespace}", Option.ModelsNamespace)
                .Replace("{Comment}", table.TableComment)
                .Replace("{ModelName}", isListQuery ? fileName + " : PageInput" : fileName)
                .Replace("{ModelProperties}", sb.ToString());
            WriteAndSave(fullPath, content);
        }

        /// <summary>
        /// 生成实体
        /// </summary>
        /// <param name="column"></param>
        /// <returns></returns>
        private string GenerateEntityProperty(DbTableColumn column)
        {
            var sb = new StringBuilder();
            if (!string.IsNullOrEmpty(column.Comments))
            {
                sb.AppendLine("\t\t/// <summary>");
                sb.AppendLine("\t\t/// " + column.Comments);
                sb.AppendLine("\t\t/// </summary>");
            }
            if (column.IsPrimaryKey)
            {
                sb.AppendLine("\t\t[Key]");
                sb.AppendLine($"\t\t[Column(\"{column.ColName.ToUpper()}\")]");
                if (column.IsIdentity)
                {
                    sb.AppendLine("\t\t[DatabaseGenerated(DatabaseGeneratedOption.Identity)]");
                }
                sb.AppendLine($"\t\tpublic {column.CSharpType} {column.Alias} " + "{get;set;}");
            }
            else
            {
                if (Option.IsPascalCase)
                {
                    sb.AppendLine($"\t\t[Column(\"{column.ColName.ToUpper()}\")]");
                }
                var colType = column.CSharpType;
                if (colType.ToLower() == "string" && column.ColumnLength.HasValue && column.ColumnLength.Value > 0)
                {
                    sb.AppendLine($"\t\t[MaxLength({column.ColumnLength.Value})]");
                }
                if (column.IsIdentity)
                {
                    sb.AppendLine("\t\t[DatabaseGenerated(DatabaseGeneratedOption.Identity)]");
                }

                if (colType.ToLower() != "string" && colType.ToLower() != "byte[]" && colType.ToLower() != "object")
                {
                    colType = colType + "?";
                }
                var colName = column.ColName;
                if (!column.Alias.IsNullOrEmpty()) colName = column.Alias;
                sb.AppendLine($"\t\tpublic {colType} {colName} " + "{get;set;}");
            }
            return sb.ToString();
        }

        /// <summary>
        /// 生成model
        /// </summary>
        /// <param name="column"></param>
        /// <returns></returns>
        private string GenerateModelsProperty(DbTableColumn column, List<GeneratorFormColumn> formColumn, string fileName)
        {
            var sb = new StringBuilder();
            if (!string.IsNullOrEmpty(column.Comments))
            {
                sb.AppendLine("\t\t/// <summary>");
                sb.AppendLine("\t\t/// " + column.Comments);
                sb.AppendLine("\t\t/// </summary>");
            }
            var colType = column.CSharpType;

            if (colType.ToLower() != "string" && colType.ToLower() != "byte[]" && colType.ToLower() != "object")
            {
                colType = colType + "?";
            }
            if (colType.ToLower() == "datetime?" && fileName.Contains("ListOutput"))
            {
                colType = "string";
            }
            if (formColumn != null && fileName.Contains("ListOutput"))
            {
                var columnParameter = formColumn.Find(f => f.vModel == column.Alias);
                if (columnParameter != null)
                {
                    switch (columnParameter.jnpfKey)
                    {
                        case "checkbox":
                            colType = "List<" + colType + ">";
                            break;
                        case "select":
                            if (columnParameter.multiple)
                            {
                                colType = "List<" + colType + ">";
                            }
                            break;
                        case "timeRange":
                            colType = "List<" + colType + ">";
                            break;
                        case "slider":
                            if (columnParameter.range)
                            {
                                colType = "List<" + colType + ">";
                            }
                            break;
                        case "address":
                            colType = "List<" + colType + ">";
                            break;
                    }
                }
            }
            if (formColumn != null && fileName.Contains("UpOutput"))
            {
                var columnParameter = formColumn.Find(f => f.vModel == column.Alias);
                if (columnParameter != null)
                {
                    switch (columnParameter.jnpfKey)
                    {
                        case "modifyTime":
                            colType = "string";
                            break;
                        case "createTime":
                            colType = "string";
                            break;
                    }
                }
            }
            var colName = column.Alias;
            sb.AppendLine($"\t\tpublic {colType} {colName.LowerFirstChar()} " + "{get;set;}");
            return sb.ToString();
        }

        /// <summary>
        /// 写文件
        /// </summary>
        /// <param name="fileName"></param>
        /// <param name="content"></param>
        public void WriteAndSave(string fileName, string content)
        {
            //实例化一个文件流--->与写入文件相关联
            using (var fs = new FileStream(fileName, FileMode.Create, FileAccess.Write))
            {
                //实例化一个StreamWriter-->与fs相关联
                using (var sw = new StreamWriter(fs))
                {
                    //开始写入
                    sw.Write(content);
                    //清空缓冲区
                    sw.Flush();
                    //关闭流
                    sw.Close();
                    fs.Close();
                }
            }
        }

        #region 功能表单代码生成模块

        /// <summary>
        /// 生成Controller层代码文件
        /// </summary>
        /// <param name="funcSwitch">功能开关</param>
        /// <param name="module">模性名称</param>
        /// <param name="modelTabele">模型表数据</param>
        /// <param name="list"></param>
        /// <param name="childTable"></param>
        /// <param name="ifExistCovered"></param>
        public void GenerateApiController(List<CodeGeneratorFuncSwitchModel> funcSwitch, string module, DbTable modelTabele, List<GeneratorFormColumn> list, List<DbTableRelationModel> childTable, bool ifExistCovered = false)
        {
            var modelTypeName = modelTabele.Alias;
            var controllerPath = Option.OutputPath + Delimiter + "Controllers";
            if (!Directory.Exists(controllerPath))
            {
                Directory.CreateDirectory(controllerPath);
            }
            var fullPath = controllerPath + Delimiter + modelTypeName + "Controller.cs";
            if (File.Exists(fullPath) && !ifExistCovered)
                return;
            //功能内容
            StringBuilder sb = new StringBuilder();
            foreach (var item in childTable)
            {
                var tableAliasName = item.table.ToPascalCase().LowerFirstChar();
                sb.AppendLine($"\t\tprivate {tableAliasName}Bll {tableAliasName}Service = new {tableAliasName}Bll();");
            }
            var funcContent = GenerateApiControllerFunction(funcSwitch, list, modelTypeName, childTable, modelTabele);
            var content = ReadTemplate("ApiControllerTemplate.txt");
            content = content.Replace("{ModelsNamespace}", Option.ModelsNamespace)
                .Replace("{ChildService}", sb.ToString())
                .Replace("{IServicesNamespace}", Option.IServicesNamespace)
                .Replace("{ControllersNamespace}", Option.ControllersNamespace)
                .Replace("{ModelTypeName}", modelTypeName)
                .Replace("{Module}", module)
                .Replace("{ControllerFunctions}", funcContent);
            WriteAndSave(fullPath, content);
        }

        /// <summary>
        /// 生成APIController功能
        /// </summary>
        /// <param name="funcSwitch"></param>
        /// <param name="modelTypeName"></param>
        /// <returns></returns>
        public string GenerateApiControllerFunction(List<CodeGeneratorFuncSwitchModel> funcSwitch, List<GeneratorFormColumn> list, string modelTypeName, List<DbTableRelationModel> childTable, DbTable modelTabele)
        {
            StringBuilder getSb = new StringBuilder();
            StringBuilder postSb = new StringBuilder();
            StringBuilder sumSb = new StringBuilder();
            var childPrimaryKey = modelTabele.Columns.Where(p => p.IsPrimaryKey == true).FirstOrDefault().Alias;
            foreach (var item in funcSwitch)
            {
                switch (item.funcSwitch)
                {
                    //分页列表
                    case "Page":
                        {
                            getSb.AppendLine("\t\t/// <summary>");
                            getSb.AppendLine("\t\t/// 获取列表");
                            getSb.AppendLine("\t\t/// </summary>");
                            getSb.AppendLine("\t\t/// <param name=\"input\">请求参数</param>");
                            getSb.AppendLine("\t\t/// <returns></returns>");
                            getSb.AppendLine("\t\t[HttpGet]");
                            getSb.AppendLine($"\t\tpublic async Task<ResponseResult> GetList({modelTypeName}ListQueryInput input)");
                            getSb.AppendLine("\t\t{");
                            getSb.AppendLine($"\t\t\tvar data = await {modelTypeName}Service.GetPageList(input);");
                            getSb.AppendLine($"\t\t\tvar outputList = data.list.MapToList<{modelTypeName}ListOutput>();");
                            //获取模板中远端数据
                            var dataTypeList = list.FindAll(l => l.dataType == "dynamic");
                            //去除查询列表中没有查询的远端数据
                            var queryList = modelTabele.Columns.Select(p => { return p.Alias.LowerFirstChar(); }).Distinct().ToList();
                            var dataTypeStringList = dataTypeList.Select(p => p.Model).Distinct().ToList();
                            //取交集list 
                            List<string> intersectList = dataTypeStringList.Intersect(queryList).ToList();
                            foreach (var items in dataTypeList)
                            {
                                var realQuery = intersectList.Find(i => i == items.Model);
                                if (realQuery != null)
                                {
                                    getSb.AppendLine($"\t\t\tvar {items.Model}List = await dataInterfaceBll.GetData(\"{items.dictionaryType}\");");
                                }
                            }
                            getSb.AppendLine("\t\t\toutputList.ForEach(o =>");
                            getSb.AppendLine("\t\t\t{");
                            //系统控件赋值
                            foreach (var items in list)
                            {
                                switch (items.jnpfKey)
                                {
                                    case "createUser":
                                        getSb.AppendLine($"\t\t\tif (!string.IsNullOrEmpty(o.{items.Model}))");
                                        getSb.AppendLine("\t\t\t{");
                                        getSb.AppendLine($"\t\t\t\tvar userEntity = await userBll.GetInfo(o.{items.Model});");
                                        getSb.AppendLine($"\t\t\t\to.{items.Model} = userEntity.RealName.ToString() + \"/\" + userEntity.Account.ToString();");
                                        getSb.AppendLine("\t\t\t}");
                                        break;
                                    case "createTime":
                                        getSb.AppendLine($"\t\t\to.{items.Model} = o.{items.Model} != null ? string.Format(\"{{0:yyyy-MM-dd HH:mm:ss}}\", Convert.ToDateTime(o.{items.Model})) : null;");
                                        break;
                                    case "modifyUser":
                                        getSb.AppendLine($"\t\t\tif (!string.IsNullOrEmpty(o.{items.Model}))");
                                        getSb.AppendLine("\t\t\t{");
                                        getSb.AppendLine($"\t\t\t\tvar userEntity = await userBll.GetInfo(o.{items.Model});");
                                        getSb.AppendLine($"\t\t\t\to.{items.Model} = userEntity.RealName.ToString() + \"/\" + userEntity.Account.ToString();");
                                        getSb.AppendLine("\t\t\t}");
                                        break;
                                    case "modifyTime":
                                        getSb.AppendLine($"\t\t\to.{items.Model} = o.{items.Model} != null ? string.Format(\"{{0:yyyy-MM-dd HH:mm:ss}}\", Convert.ToDateTime(o.{items.Model})) : null;");
                                        break;
                                    case "currOrganize":
                                        getSb.AppendLine($"\t\t\tif (!string.IsNullOrEmpty(o.{items.Model}))");
                                        getSb.AppendLine("\t\t\t{");
                                        getSb.AppendLine($"\t\t\t\to.{items.Model} = (await organizeBll.GetList()).Find(p => p.Id == o.{items.Model}).FullName;");
                                        getSb.AppendLine("\t\t\t}");
                                        break;
                                    case "currDept":
                                        getSb.AppendLine($"\t\t\tif (!string.IsNullOrEmpty(o.{items.Model}))");
                                        getSb.AppendLine("\t\t\t{");
                                        getSb.AppendLine($"\t\t\t\to.{items.Model} = (await organizeBll.GetList()).Find(p => p.Id == o.{items.Model}).FullName;");
                                        getSb.AppendLine("\t\t\t}");
                                        break;
                                    case "currPosition":
                                        getSb.AppendLine($"\t\t\tif (!string.IsNullOrEmpty(o.{items.Model}))");
                                        getSb.AppendLine("\t\t\t{");
                                        getSb.AppendLine($"\t\t\t\to.{items.Model} = (await positionBll.GetList()).Find(p => p.Id == o.{items.Model}).FullName;");
                                        getSb.AppendLine("\t\t\t}");
                                        break;
                                }
                            }
                            foreach (var items in dataTypeList)
                            {
                                var realQuery = intersectList.Find(i => i == items.Model);
                                if (realQuery != null && items.multiple == false)
                                {
                                    getSb.AppendLine($"\t\t\t\to.{items.Model} = o.{items.Model} != null ? {items.Model}List.Select($\"{items.props.value} = '{{o.{items.Model}}}'\").FirstOrDefault()[\"{items.props.label}\"].ToString() : null;");
                                }
                            }
                            var formatList = list.FindAll(l => l.format != null && l.jnpfKey != "dateRange");
                            foreach (var items in formatList)
                            {
                                var isExist = modelTabele.Columns.Where(c => c.Alias == items.vModel).FirstOrDefault();
                                if (isExist != null)
                                {
                                    getSb.AppendLine($"\t\t\t\to.{items.Model}=o.{items.Model} !=null ? string.Format(\"{{0:{items.format}}}\",Convert.ToDateTime(o.{items.Model})):null;");
                                }
                            }
                            var multipleList = list.FindAll(l => l.multiple == true);
                            foreach (var items in multipleList)
                            {
                                var isExist = modelTabele.Columns.Where(c => c.Alias == items.vModel).FirstOrDefault();
                                if (isExist != null)
                                {
                                    getSb.AppendLine($"\t\t\t\to.{items.Model}=data.list.Find(p => p.{childPrimaryKey} == o.{childPrimaryKey.LowerFirstChar()}).{items.vModel}.Split(',').ToList();");
                                }
                            }
                            getSb.AppendLine("\t\t\t});");
                            getSb.AppendLine("\t\t\tvar output = new PageResult()");
                            getSb.AppendLine("\t\t\t{");
                            getSb.AppendLine($"\t\t\t\tlist = outputList,");
                            getSb.AppendLine("\t\t\t\tpagination = data.pagination");
                            getSb.AppendLine("\t\t\t};");
                            getSb.AppendLine("\t\t\treturn Success(output);");
                            getSb.AppendLine("\t\t}");
                            getSb.AppendLine();
                        }
                        break;
                    //无分页列表
                    case "noPage":
                        {
                            getSb.AppendLine("\t\t/// <summary>");
                            getSb.AppendLine("\t\t/// 获取列表");
                            getSb.AppendLine("\t\t/// </summary>");
                            getSb.AppendLine("\t\t/// <param name=\"input\">过滤条件</param>");
                            getSb.AppendLine("\t\t/// <returns></returns>");
                            getSb.AppendLine("\t\t[HttpGet]");
                            getSb.AppendLine("\t\tpublic async Task<ResponseResult> GetList({modelTypeName}ListQueryInput input)");
                            getSb.AppendLine("\t\t{");
                            getSb.AppendLine("\t\t\ttry");
                            getSb.AppendLine("\t\t\t{");
                            getSb.AppendLine($"\t\t\t\tvar data = await {modelTypeName}Service.GetList(input);");
                            getSb.AppendLine($"\t\t\t\tvar output=data.MapToList<{modelTypeName}ListOutput>();");
                            //获取模板中远端数据
                            var dataTypeList = list.FindAll(l => l.dataType == "dynamic");
                            //去除查询列表中没有查询的远端数据
                            var queryList = modelTabele.Columns.Select(p => { return p.Alias.LowerFirstChar(); }).Distinct().ToList();
                            var dataTypeStringList = dataTypeList.Select(p => p.Model).Distinct().ToList();
                            //取交集list 
                            List<string> intersectList = dataTypeStringList.Intersect(queryList).ToList();
                            foreach (var items in dataTypeList)
                            {
                                var realQuery = intersectList.Find(i => i == items.Model);
                                if (realQuery != null)
                                {
                                    getSb.AppendLine($"\t\t\tvar {items.Model}List = await dataInterfaceBll.GetData(\"{items.dictionaryType}\");");
                                }
                            }
                            getSb.AppendLine("\t\t\t\toutputList.ForEach(o =>");
                            getSb.AppendLine("\t\t\t\t{");
                            //系统控件赋值
                            foreach (var items in list)
                            {
                                switch (items.jnpfKey)
                                {
                                    case "createUser":
                                        getSb.AppendLine($"\t\t\tif (!string.IsNullOrEmpty(o.{items.Model}))");
                                        getSb.AppendLine("\t\t\t{");
                                        getSb.AppendLine($"\t\t\t\tvar userEntity = await userBll.GetInfo(o.{items.Model});");
                                        getSb.AppendLine($"\t\t\t\to.{items.Model} = userEntity.RealName.ToString() + \"/\" + userEntity.Account.ToString();");
                                        getSb.AppendLine("\t\t\t}");
                                        break;
                                    case "createTime":
                                        getSb.AppendLine($"\t\t\to.{items.Model} = o.{items.Model} != null ? string.Format(\"{{0:yyyy-MM-dd HH:mm:ss}}\", Convert.ToDateTime(o.{items.Model})) : null;");
                                        break;
                                    case "modifyUser":
                                        getSb.AppendLine($"\t\t\tif (!string.IsNullOrEmpty(o.{items.Model}))");
                                        getSb.AppendLine("\t\t\t{");
                                        getSb.AppendLine($"\t\t\t\tvar userEntity = await userBll.GetInfo(o.{items.Model});");
                                        getSb.AppendLine($"\t\t\t\to.{items.Model} = userEntity.RealName.ToString() + \"/\" + userEntity.Account.ToString();");
                                        getSb.AppendLine("\t\t\t}");
                                        break;
                                    case "modifyTime":
                                        getSb.AppendLine($"\t\t\to.{items.Model} = o.{items.Model} != null ? string.Format(\"{{0:yyyy-MM-dd HH:mm:ss}}\", Convert.ToDateTime(o.{items.Model})) : null;");
                                        break;
                                    case "currOrganize":
                                        getSb.AppendLine($"\t\t\tif (!string.IsNullOrEmpty(o.{items.Model}))");
                                        getSb.AppendLine("\t\t\t{");
                                        getSb.AppendLine($"\t\t\t\to.{items.Model} = (await organizeBll.GetList()).Find(p => p.Id == o.{items.Model}).FullName;");
                                        getSb.AppendLine("\t\t\t}");
                                        break;
                                    case "currDept":
                                        getSb.AppendLine($"\t\t\tif (!string.IsNullOrEmpty(o.{items.Model}))");
                                        getSb.AppendLine("\t\t\t{");
                                        getSb.AppendLine($"\t\t\t\to.{items.Model} = (await organizeBll.GetList()).Find(p => p.Id == o.{items.Model}).FullName;");
                                        getSb.AppendLine("\t\t\t}");
                                        break;
                                    case "currPosition":
                                        getSb.AppendLine($"\t\t\tif (!string.IsNullOrEmpty(o.{items.Model}))");
                                        getSb.AppendLine("\t\t\t{");
                                        getSb.AppendLine($"\t\t\t\to.{items.Model} = (await positionBll.GetList()).Find(p => p.Id == o.{items.Model}).FullName;");
                                        getSb.AppendLine("\t\t\t}");
                                        break;
                                }
                            }
                            foreach (var items in dataTypeList)
                            {
                                var realQuery = intersectList.Find(i => i == items.Model);
                                if (realQuery != null && items.multiple == false)
                                {
                                    getSb.AppendLine($"\t\t\t\to.{items.Model}={items.Model}List.Select($\"{items.props.value} = '{{o.{items.Model}}}'\")[0][\"{items.props.label}\"].ToString();");
                                }
                            }
                            var formatList = list.FindAll(l => l.format != null && l.jnpfKey != "dateRange");
                            foreach (var items in formatList)
                            {
                                var isExist = modelTabele.Columns.Where(c => c.Alias == items.vModel).FirstOrDefault();
                                if (isExist != null)
                                {
                                    getSb.AppendLine($"\t\t\t\to.{items.Model}=o.{items.Model} !=null ? string.Format(\"{{0:{items.format}}}\",Convert.ToDateTime(o.{items.Model})):null;");
                                }
                            }
                            var multipleList = list.FindAll(l => l.multiple == true);
                            foreach (var items in multipleList)
                            {
                                var isExist = modelTabele.Columns.Where(c => c.Alias == items.vModel).FirstOrDefault();
                                if (isExist != null)
                                {
                                    getSb.AppendLine($"\t\t\t\to.{items.Model}=data.list.Find(p => p.{childPrimaryKey} == o.{childPrimaryKey.LowerFirstChar()}).{items.vModel}.Split(',').ToList();");
                                }
                            }
                            getSb.AppendLine("\t\t\t\t});");
                            getSb.AppendLine("\t\t\t\treturn Success(new { list = output });");
                            getSb.AppendLine("\t\t\t}");
                            getSb.AppendLine("\t\t\tcatch (Exception ex)");
                            getSb.AppendLine("\t\t\t{");
                            getSb.AppendLine("\t\t\t\tvar data = new List<TestpositionssEntity>();");
                            getSb.AppendLine("\t\t\t\treturn Success(new { list = data });");
                            getSb.AppendLine("\t\t\t}");
                            getSb.AppendLine("\t\t}");
                            getSb.AppendLine();
                        }
                        break;
                    //新建
                    case "add":
                        {
                            postSb.AppendLine("\t\t/// <summary>");
                            postSb.AppendLine("\t\t/// 新建");
                            postSb.AppendLine("\t\t/// </summary>");
                            postSb.AppendLine("\t\t/// <param name=\"input\">新建输入</param>");
                            postSb.AppendLine("\t\t/// <returns></returns>");
                            postSb.AppendLine("\t\t[HttpPost]");
                            postSb.AppendLine($"\t\tpublic async Task<ResponseResult> Create([FromBody] {modelTypeName}CrInput input)");
                            postSb.AppendLine("\t\t{");
                            postSb.AppendLine($"\t\t\tvar entity = input.MapTo<{modelTypeName}Entity>();");
                            foreach (var column in list)
                            {
                                switch (column.jnpfKey)
                                {
                                    case "billRule":
                                        postSb.AppendLine($"\t\t\tentity.{column.vModel} = await billRuleService.GetBillNumber(\"{column.billRule}\", true);");
                                        break;
                                    case "checkbox":
                                        postSb.AppendLine($"\t\t\tentity.{column.vModel} = string.Join(\",\", input.{column.Model});");
                                        break;
                                    case "select":
                                        if (column.multiple)
                                        {
                                            postSb.AppendLine($"\t\t\tentity.{column.vModel} = string.Join(\",\", input.{column.Model});");
                                        }
                                        break;
                                    case "timeRange":
                                        postSb.AppendLine($"\t\t\tentity.{column.vModel} = string.Join(\",\", input.{column.Model});");
                                        break;
                                    case "dateRange":
                                        postSb.AppendLine($"\t\t\tentity.{column.vModel} = string.Join(\",\", input.{column.Model});");
                                        break;
                                    case "address":
                                        break;
                                    default:
                                        break;
                                }
                            }
                            postSb.AppendLine($"\t\t\tawait {modelTypeName}Service.Create(entity);");
                            if (childTable.Count > 0)
                            {
                                foreach (var child in childTable)
                                {
                                    var name = child.table.ToPascalCase().LowerFirstChar();
                                    postSb.AppendLine($"\t\t\tforeach (var item in input.{name})");
                                    postSb.AppendLine("\t\t\t{");
                                    postSb.AppendLine($"\t\t\t\tvar childEntity = item.MapTo<{name}Entity>();");
                                    var childRelationField = child.tableField.Replace("F_", "").Replace("f_", "").ToPascalCase();
                                    var relationField = child.relationField.Replace("F_", "").Replace("f_", "").ToPascalCase();
                                    postSb.AppendLine($"\t\t\t\tchildEntity.{childRelationField} = entity.{relationField};");
                                    postSb.AppendLine($"\t\t\t\tawait {name}Service.Create(childEntity);");
                                    postSb.AppendLine("\t\t\t}");
                                }
                            }
                            postSb.AppendLine("\t\t\treturn Success(\"新建成功\");");
                            postSb.AppendLine("\t\t}");
                            postSb.AppendLine();
                        }
                        break;
                    //编辑
                    case "edit":
                        {
                            postSb.AppendLine("\t\t/// <summary>");
                            postSb.AppendLine("\t\t/// 编辑");
                            postSb.AppendLine("\t\t/// </summary>");
                            postSb.AppendLine("\t\t/// <param name=\"id\">主键id</param>");
                            postSb.AppendLine("\t\t/// <param name=\"input\">编辑输入</param>");
                            postSb.AppendLine("\t\t/// <returns></returns>");
                            postSb.AppendLine("\t\t[HttpPut(\"{id}\")]");
                            postSb.AppendLine($"\t\tpublic async Task<ResponseResult> Update(string id, [FromBody] {modelTypeName}CrInput input)");
                            postSb.AppendLine("\t\t{");
                            postSb.AppendLine($"\t\t\tvar entity = input.MapTo<{modelTypeName}Entity>();");
                            foreach (var column in list)
                            {
                                switch (column.jnpfKey)
                                {
                                    case "billRule":
                                        postSb.AppendLine($"\t\t\tentity.{column.vModel} = await billRuleService.GetBillNumber(\"{column.billRule}\", true);");
                                        break;
                                    case "checkbox":
                                        postSb.AppendLine($"\t\t\tentity.{column.vModel} = string.Join(\",\", input.{column.Model});");
                                        break;
                                    case "select":
                                        if (column.multiple)
                                        {
                                            postSb.AppendLine($"\t\t\tentity.{column.vModel} = string.Join(\",\", input.{column.Model});");
                                        }
                                        break;
                                    case "timeRange":
                                        postSb.AppendLine($"\t\t\tentity.{column.vModel} = string.Join(\",\", input.{column.Model});");
                                        break;
                                    case "dateRange":
                                        postSb.AppendLine($"\t\t\tentity.{column.vModel} = string.Join(\",\", input.{column.Model});");
                                        break;
                                    case "address":
                                        break;
                                    default:
                                        break;
                                }
                            }
                            if (childTable.Count > 0)
                            {
                                foreach (var child in childTable)
                                {
                                    var name = child.table.ToPascalCase().LowerFirstChar();
                                    postSb.AppendLine($"\t\t\tawait {name}Service.Delete(id);");
                                    postSb.AppendLine($"\t\t\tforeach (var item in input.{name})");
                                    postSb.AppendLine("\t\t\t{");
                                    postSb.AppendLine($"\t\t\t\tvar childEntity = item.MapTo<{name}Entity>();");
                                    var childRelationField = child.tableField.Replace("F_", "").Replace("f_", "").ToPascalCase();
                                    postSb.AppendLine($"\t\t\t\tchildEntity.{childRelationField} = id;");
                                    postSb.AppendLine($"\t\t\t\tawait {name}Service.Create(childEntity);");
                                    postSb.AppendLine("\t\t\t}");
                                }
                            }
                            postSb.AppendLine($"\t\t\tvar isOk = await {modelTypeName}Service.Update(id, entity);");
                            postSb.AppendLine("\t\t\treturn isOk > 0 ? Success(\"修改成功\") : Error(\"修改失败\");");
                            postSb.AppendLine("\t\t}");
                            postSb.AppendLine();
                        }
                        break;
                    //删除
                    case "remove":
                        {
                            postSb.AppendLine("\t\t/// <summary>");
                            postSb.AppendLine("\t\t/// 删除接口");
                            postSb.AppendLine("\t\t/// </summary>");
                            postSb.AppendLine("\t\t/// <param name=\"id\">主键id</param>");
                            postSb.AppendLine("\t\t/// <returns></returns>");
                            postSb.AppendLine("\t\t[HttpDelete(\"{id}\")]");
                            postSb.AppendLine("\t\tpublic async Task<ResponseResult> Delete(string id)");
                            postSb.AppendLine("\t\t{");
                            postSb.AppendLine($"\t\t\tvar entity = await {modelTypeName}Service.GetInfo(id);");
                            if (childTable.Count > 0)
                            {
                                foreach (var child in childTable)
                                {
                                    var name = child.table.ToPascalCase();
                                    postSb.AppendLine($"\t\t\tawait {name.LowerFirstChar()}Service.Delete(id);");
                                }
                            }
                            postSb.AppendLine($"\t\t\tvar isOk = await {modelTypeName}Service.Delete(entity);");
                            postSb.AppendLine("\t\t\treturn isOk > 0 ? Success(\"删除成功\") : Error(\"删除失败\");");
                            postSb.AppendLine("\t\t}");
                            postSb.AppendLine();
                        }
                        break;
                    //导出
                    case "download":
                        {
                            postSb.AppendLine("\t\t/// <summary>");
                            postSb.AppendLine("\t\t/// 导出");
                            postSb.AppendLine("\t\t/// </summary>");
                            postSb.AppendLine("\t\t/// <returns></returns>");
                            postSb.AppendLine("\t\t[HttpPost(\"Actions/Export\")]");
                            postSb.AppendLine($"\t\tpublic async Task<ResponseResult> Export([FromBody] {modelTypeName}ListQueryInput input)");
                            postSb.AppendLine("\t\t{");
                            postSb.AppendLine($"\t\t\tvar exportData = new List<{modelTypeName}Entity>();");
                            postSb.AppendLine("\t\t\tif (input.dataType == 0)");
                            postSb.AppendLine("\t\t\t{");
                            postSb.AppendLine($"\t\t\t\tvar data = await {modelTypeName}Service.GetPageList(input);");
                            postSb.AppendLine("\t\t\t\texportData = data.list;");
                            postSb.AppendLine("\t\t\t}");
                            postSb.AppendLine("\t\t\telse {");
                            postSb.AppendLine($"\t\t\t\texportData= await {modelTypeName}Service.GetList(input);");
                            postSb.AppendLine("\t\t\t}");
                            StringBuilder columnSb = new StringBuilder();
                            foreach (var column in list)
                            {
                                columnSb.Append($"{{\\\"value\\\":\\\"{column.placeholder}\\\",\\\"field\\\":\\\"{column.Model}\\\"}},");
                            }
                            string paramList = string.Format("[{0}]", columnSb.ToString().TrimEnd(','));
                            postSb.AppendLine($"\t\t\tList<ParamsModel> paramList = \"{paramList}\".ToList<ParamsModel>();");
                            postSb.AppendLine("\t\t\tvar userinfo = UserProvider.Instance.Get();");
                            postSb.AppendLine("\t\t\tExcelConfig excelconfig = new ExcelConfig();");
                            postSb.AppendLine($"\t\t\texcelconfig.FileName = \"{modelTabele.TableComment}.xls\";");
                            postSb.AppendLine("\t\t\texcelconfig.HeadFont = \"微软雅黑\";");
                            postSb.AppendLine("\t\t\texcelconfig.HeadPoint = 10;");
                            postSb.AppendLine("\t\t\texcelconfig.IsAllSizeColumn = true;");
                            postSb.AppendLine("\t\t\texcelconfig.ColumnModel = new List<ExcelColumnModel>();");
                            postSb.AppendLine("\t\t\tList<string> selectKeyList = input.selectKey.Split(',').ToList<string>();");
                            postSb.AppendLine("\t\t\tforeach (var item in selectKeyList)");
                            postSb.AppendLine("\t\t\t{");
                            postSb.AppendLine("\t\t\t\tvar isExist = paramList.Find(p => p.field == item);");
                            postSb.AppendLine("\t\t\t\tif (isExist != null)");
                            postSb.AppendLine("\t\t\t\t{");
                            postSb.AppendLine("\t\t\t\t\texcelconfig.ColumnModel.Add(new ExcelColumnModel() { Column = isExist.field.UpperFirstChar(), ExcelColumn = isExist.value });");
                            postSb.AppendLine("\t\t\t\t}");
                            postSb.AppendLine("\t\t\t}");
                            postSb.AppendLine("\t\t\tvar addPath = ConfigurationKey.TemporaryFilePath + excelconfig.FileName;");
                            postSb.AppendLine($"\t\t\tExcelExportHelper<{modelTypeName}Entity>.Export(exportData, excelconfig, addPath);");
                            postSb.AppendLine("\t\t\treturn Success(new { name = excelconfig.FileName, url = \"/api/Common/Download?encryption=\" + userinfo.Id + \"|\" + excelconfig.FileName });");
                            postSb.AppendLine("\t\t}");
                        }
                        break;
                    case "info":
                        {
                            getSb.AppendLine("\t\t/// <summary>");
                            getSb.AppendLine("\t\t/// 获取信息");
                            getSb.AppendLine("\t\t/// </summary>");
                            getSb.AppendLine("\t\t/// <param name=\"id\">主键id</param>");
                            getSb.AppendLine("\t\t/// <returns></returns>");
                            getSb.AppendLine("\t\t[HttpGet(\"{id}\")]");
                            getSb.AppendLine("\t\tpublic async Task<ResponseResult> GetInfo(string id)");
                            getSb.AppendLine("\t\t{");
                            getSb.AppendLine($"\t\t\tvar data = await {modelTypeName}Service.GetInfo(id);");
                            getSb.AppendLine($"\t\t\tvar output = data.MapTo<{modelTypeName}UpOutput>();");
                            foreach (var items in list)
                            {
                                switch (items.jnpfKey)
                                {
                                    case "createUser":
                                        getSb.AppendLine($"\t\t\tif (!string.IsNullOrEmpty(output.{items.Model}))");
                                        getSb.AppendLine("\t\t\t{");
                                        getSb.AppendLine($"\t\t\t\tvar userEntity = await userBll.GetInfo(output.{items.Model});");
                                        getSb.AppendLine($"\t\t\t\toutput.{items.Model} = userEntity.RealName.ToString() + \"/\" + userEntity.Account.ToString();");
                                        getSb.AppendLine("\t\t\t}");
                                        break;
                                    case "createTime":
                                        getSb.AppendLine($"\t\t\toutput.{items.Model} = output.{items.Model} != null ? string.Format(\"{{0:yyyy-MM-dd HH:mm:ss}}\", Convert.ToDateTime(output.{items.Model})) : null;");
                                        break;
                                    case "modifyUser":
                                        getSb.AppendLine($"\t\t\tif (!string.IsNullOrEmpty(output.{items.Model}))");
                                        getSb.AppendLine("\t\t\t{");
                                        getSb.AppendLine($"\t\t\t\tvar userEntity = await userBll.GetInfo(output.{items.Model});");
                                        getSb.AppendLine($"\t\t\t\toutput.{items.Model} = userEntity.RealName.ToString() + \"/\" + userEntity.Account.ToString();");
                                        getSb.AppendLine("\t\t\t}");
                                        break;
                                    case "modifyTime":
                                        getSb.AppendLine($"\t\t\toutput.{items.Model} = output.{items.Model} != null ? string.Format(\"{{0:yyyy-MM-dd HH:mm:ss}}\", Convert.ToDateTime(output.{items.Model})) : null;");
                                        break;
                                    case "currOrganize":
                                        getSb.AppendLine($"\t\t\tif (!string.IsNullOrEmpty(output.{items.Model}))");
                                        getSb.AppendLine("\t\t\t{");
                                        getSb.AppendLine($"\t\t\t\toutput.{items.Model} = (await organizeBll.GetList()).Find(p => p.Id == output.{items.Model}).FullName;");
                                        getSb.AppendLine("\t\t\t}");
                                        break;
                                    case "currDept":
                                        getSb.AppendLine($"\t\t\tif (!string.IsNullOrEmpty(output.{items.Model}))");
                                        getSb.AppendLine("\t\t\t{");
                                        getSb.AppendLine($"\t\t\t\toutput.{items.Model} = (await organizeBll.GetList()).Find(p => p.Id == output.{items.Model}).FullName;");
                                        getSb.AppendLine("\t\t\t}");
                                        break;
                                    case "currPosition":
                                        getSb.AppendLine($"\t\t\tif (!string.IsNullOrEmpty(output.{items.Model}))");
                                        getSb.AppendLine("\t\t\t{");
                                        getSb.AppendLine($"\t\t\t\toutput.{items.Model} = (await positionBll.GetList()).Find(p => p.Id == output.{items.Model}).FullName;");
                                        getSb.AppendLine("\t\t\t}");
                                        break;
                                }
                            }
                            if (childTable.Count > 0)
                            {
                                foreach (var items in childTable)
                                {
                                    var child = items.table.ToPascalCase().LowerFirstChar();
                                    getSb.AppendLine($"\t\t\tList<{child}Entity> {child}List= await {child}Service.GetInfo(id);");
                                    getSb.AppendLine($"\t\t\toutput.{child} = {child}List.MapToList<{child}UpOutput>();");
                                }
                            }
                            getSb.AppendLine("\t\t\treturn Success(output);");
                            getSb.AppendLine("\t\t}");
                            getSb.AppendLine();
                        }
                        break;
                }
            }
            sumSb.AppendLine("\t\t#region GET");
            sumSb.AppendLine();
            sumSb.Append(getSb.ToString());
            sumSb.AppendLine("\t\t#endregion");
            sumSb.AppendLine();
            sumSb.AppendLine("\t\t#region POST");
            sumSb.AppendLine();
            sumSb.Append(postSb.ToString());
            sumSb.AppendLine("\t\t#endregion");
            return sumSb.ToString();
        }

        /// <summary>
        /// 生成Bll层代码文件
        /// </summary>
        /// <param name="funcSwitch">功能开关</param>
        /// <param name="modelTypeName"></param>
        /// <param name="ifExistCovered"></param>
        public void GenerateBll(List<CodeGeneratorFuncSwitchModel> funcSwitch, DbTable table, List<GeneratorFormColumn> list, bool ifExistCovered = false)
        {
            var repositoryPath = Option.OutputPath + Delimiter + "Logic";
            if (!Directory.Exists(repositoryPath))
            {
                Directory.CreateDirectory(repositoryPath);
            }
            var fullPath = repositoryPath + Delimiter + table.Alias + "Bll.cs";
            if (File.Exists(fullPath) && !ifExistCovered)
                return;
            //功能内容
            StringBuilder sb = new StringBuilder();
            var funcContent = GenerateBllFunction(funcSwitch, table, list);
            var content = ReadTemplate("RepositoryTemplate.txt");
            content = content.Replace("{ModelsNamespace}", Option.ModelsNamespace)
                .Replace("{RepositoriesNamespace}", Option.RepositoriesNamespace)
                .Replace("{ModelTypeName}", table.Alias)
                .Replace("{ChildService}", "")
                .Replace("{BllFunctions}", funcContent);
            WriteAndSave(fullPath, content);
        }

        /// <summary>
        /// 生成BLL功能
        /// </summary>
        /// <param name="funcSwitch"></param>
        /// <param name="modelTypeName"></param>
        /// <returns></returns>
        public string GenerateBllFunction(List<CodeGeneratorFuncSwitchModel> funcSwitch, DbTable table, List<GeneratorFormColumn> list)
        {
            string modelTypeName = table.Alias;
            var tableColumns = table.Columns.ToList();
            StringBuilder sb = new StringBuilder();
            foreach (var item in funcSwitch)
            {
                switch (item.funcSwitch)
                {
                    //分页列表
                    case "Page":
                        {
                            if (item.tableRelationTag == 0)
                            {
                                sb.AppendLine("\t\t/// <summary>");
                                sb.AppendLine("\t\t/// 获取列表");
                                sb.AppendLine("\t\t/// </summary>");
                                sb.AppendLine("\t\t/// <param name=\"input\">请求参数</param>");
                                sb.AppendLine("\t\t/// <returns></returns>");
                                sb.AppendLine($"\t\tpublic async Task<PageResult<{modelTypeName}Entity>> GetPageList({modelTypeName}ListQueryInput input)");
                                sb.AppendLine("\t\t{");
                                sb.AppendLine("\t\t\ttry");
                                sb.AppendLine("\t\t\t{");
                                sb.AppendLine("\t\t\t\treturn await service.GetPageList(input);");
                                sb.AppendLine("\t\t\t}");
                                sb.AppendLine("\t\t\tcatch (Exception ex)");
                                sb.AppendLine("\t\t\t{");
                                sb.AppendLine("\t\t\t\tthrow ExceptionEx.Throw(ex);");
                                sb.AppendLine("\t\t\t}");
                                sb.AppendLine("\t\t}");
                                sb.AppendLine();
                            }
                        }
                        break;
                    //无分页列表
                    case "noPage":
                        {
                            if (item.tableRelationTag == 0)
                            {
                                sb.AppendLine("\t\t/// <summary>");
                                sb.AppendLine("\t\t/// 获取列表");
                                sb.AppendLine("\t\t/// </summary>");
                                sb.AppendLine("\t\t/// <param name=\"input\">过滤条件</param>");
                                sb.AppendLine("\t\t/// <returns></returns>");
                                sb.AppendLine($"\t\tpublic async Task<List<{modelTypeName}Entity>> GetList({modelTypeName}ListQueryInput input)");
                                sb.AppendLine("\t\t{");
                                sb.AppendLine("\t\t\ttry");
                                sb.AppendLine("\t\t\t{");
                                sb.AppendLine($"\t\t\t\treturn await service.GetList(input);");
                                sb.AppendLine("\t\t\t}");
                                sb.AppendLine("\t\t\tcatch (Exception ex)");
                                sb.AppendLine("\t\t\t{");
                                sb.AppendLine("\t\t\t\tthrow ExceptionEx.Throw(ex);");
                                sb.AppendLine("\t\t\t}");
                                sb.AppendLine("\t\t}");
                                sb.AppendLine();
                            }
                        }
                        break;
                    //新建
                    case "add":
                        {
                            if (item.tableRelationTag == 0)
                            {
                                sb.AppendLine("\t\t/// <summary>");
                                sb.AppendLine("\t\t/// 创建信息");
                                sb.AppendLine("\t\t/// </summary>");
                                sb.AppendLine("\t\t/// <param name=\"entity\">实体对象</param>");
                                sb.AppendLine("\t\t/// <returns></returns>");
                                sb.AppendLine($"\t\tpublic async Task<int> Create({modelTypeName}Entity entity)");
                                sb.AppendLine("\t\t{");
                                sb.AppendLine("\t\t\ttry");
                                sb.AppendLine("\t\t\t{");
                                var columnPrimary = tableColumns.Find(c => c.IsPrimaryKey);
                                sb.AppendLine($"\t\t\t\tentity.{columnPrimary.Alias} = CommonHelper.Guid;");
                                //sb.AppendLine("\t\t\t\tentity.EnabledMark = 1;");
                                foreach (var column in list)
                                {
                                    var entity = table.Columns.ToList().Find(c => c.Alias.ToLower() == column.Model.ToLower());
                                    switch (column.jnpfKey)
                                    {
                                        case "createUser":
                                            sb.AppendLine($"\t\t\t\tentity.{entity.Alias} = UserProvider.Instance.Get().UserId;");
                                            break;
                                        case "createTime":
                                            sb.AppendLine($"\t\t\t\tentity.{entity.Alias} = DateTime.Now;");
                                            break;
                                        //所属公司
                                        case "currOrganize":
                                            sb.AppendLine($"\t\t\t\tentity.{entity.Alias} = UserProvider.Instance.Get().OrganizeId;");
                                            break;
                                        //所属部门
                                        case "currDept":
                                            sb.AppendLine($"\t\t\t\tentity.{entity.Alias} = UserProvider.Instance.Get().OrganizeId;");
                                            break;
                                        //所属岗位
                                        case "currPosition":
                                            sb.AppendLine($"\t\t\t\tentity.{entity.Alias} = UserProvider.Instance.Get().PositionIds.ToList<string>().FirstOrDefault();");
                                            break;
                                        default:
                                            break;
                                    }
                                }
                                sb.AppendLine("\t\t\t\treturn await service.Create(entity);");
                                sb.AppendLine("\t\t\t}");
                                sb.AppendLine("\t\t\tcatch (Exception ex)");
                                sb.AppendLine("\t\t\t{");
                                sb.AppendLine("\t\t\t\tthrow ExceptionEx.Throw(ex);");
                                sb.AppendLine("\t\t\t}");
                                sb.AppendLine("\t\t}");
                                sb.AppendLine();
                            }
                            else
                            {
                                sb.AppendLine("\t\t/// <summary>");
                                sb.AppendLine("\t\t/// 创建信息");
                                sb.AppendLine("\t\t/// </summary>");
                                sb.AppendLine("\t\t/// <param name=\"entity\">实体对象</param>");
                                sb.AppendLine("\t\t/// <returns></returns>");
                                sb.AppendLine($"\t\tpublic async Task<int> Create({modelTypeName}Entity entity)");
                                sb.AppendLine("\t\t{");
                                sb.AppendLine("\t\t\ttry");
                                sb.AppendLine("\t\t\t{");
                                var columnPrimary = tableColumns.Find(c => c.IsPrimaryKey);
                                sb.AppendLine($"\t\t\t\tentity.{columnPrimary.Alias} = CommonHelper.Guid;");
                                sb.AppendLine("\t\t\t\treturn await service.Create(entity);");
                                sb.AppendLine("\t\t\t}");
                                sb.AppendLine("\t\t\tcatch (Exception ex)");
                                sb.AppendLine("\t\t\t{");
                                sb.AppendLine("\t\t\t\tthrow ExceptionEx.Throw(ex);");
                                sb.AppendLine("\t\t\t}");
                                sb.AppendLine("\t\t}");
                                sb.AppendLine();
                            }
                        }
                        break;
                    //编辑
                    case "edit":
                        {
                            if (item.tableRelationTag == 0)
                            {
                                sb.AppendLine("\t\t/// <summary>");
                                sb.AppendLine("\t\t/// 更新信息");
                                sb.AppendLine("\t\t/// </summary>");
                                sb.AppendLine("\t\t/// <param name=\"id\">主键值</param>");
                                sb.AppendLine("\t\t/// <param name=\"entity\">实体对象</param>");
                                sb.AppendLine("\t\t/// <returns></returns>");
                                sb.AppendLine($"\t\tpublic async Task<int> Update(string id, {modelTypeName}Entity entity)");
                                sb.AppendLine("\t\t{");
                                sb.AppendLine("\t\t\ttry");
                                sb.AppendLine("\t\t\t{");
                                var columnPrimary = tableColumns.Find(c => c.IsPrimaryKey);
                                sb.AppendLine($"\t\t\t\tentity.{columnPrimary.Alias} =id;");
                                foreach (var column in list)
                                {
                                    var entity = table.Columns.ToList().Find(c => c.Alias.ToLower() == column.Model.ToLower());
                                    switch (column.jnpfKey)
                                    {
                                        case "modifyTime":
                                            sb.AppendLine($"\t\t\t\tentity.{entity.Alias} = DateTime.Now;");
                                            break;
                                        case "modifyUser":
                                            sb.AppendLine($"\t\t\t\tentity.{entity.Alias} = UserProvider.Instance.Get().UserId;");
                                            break;
                                        default:
                                            break;
                                    }
                                }
                                sb.AppendLine("\t\t\t\treturn await service.Update(entity);");
                                sb.AppendLine("\t\t\t}");
                                sb.AppendLine("\t\t\tcatch (Exception ex)");
                                sb.AppendLine("\t\t\t{");
                                sb.AppendLine("\t\t\t\tthrow ExceptionEx.Throw(ex);");
                                sb.AppendLine("\t\t\t}");
                                sb.AppendLine("\t\t}");
                                sb.AppendLine();
                            }
                        }
                        break;
                    //删除
                    case "remove":
                        {
                            if (item.tableRelationTag == 0)
                            {
                                sb.AppendLine("\t\t/// <summary>");
                                sb.AppendLine("\t\t/// 删除信息");
                                sb.AppendLine("\t\t/// </summary>");
                                sb.AppendLine("\t\t/// <param name=\"entity\">实体对象</param>");
                                sb.AppendLine("\t\t/// <returns></returns>");
                                sb.AppendLine($"\t\tpublic async Task<int> Delete({modelTypeName}Entity entity)");
                                sb.AppendLine("\t\t{");
                                sb.AppendLine("\t\t\ttry");
                                sb.AppendLine("\t\t\t{");
                                foreach (var column in list)
                                {
                                    switch (column.jnpfKey)
                                    {
                                        case "deleteTime":
                                            sb.AppendLine("\t\t\t\tentity.DeleteTime = DateTime.Now;");
                                            break;
                                        case "deleteUser":
                                            sb.AppendLine("\t\t\t\tentity.DeleteUserId = UserProvider.Instance.Get().UserId;");
                                            break;
                                        default:
                                            break;
                                    }
                                }
                                //sb.AppendLine("\t\t\t\tentity.DeleteMark = 1;");
                                sb.AppendLine("\t\t\t\treturn await service.Delete(entity);");
                                sb.AppendLine("\t\t\t}");
                                sb.AppendLine("\t\t\tcatch (Exception ex)");
                                sb.AppendLine("\t\t\t{");
                                sb.AppendLine("\t\t\t\tthrow ExceptionEx.Throw(ex);");
                                sb.AppendLine("\t\t\t}");
                                sb.AppendLine("\t\t}");
                                sb.AppendLine();
                            }
                            else
                            {
                                sb.AppendLine("\t\t/// <summary>");
                                sb.AppendLine("\t\t/// 删除信息");
                                sb.AppendLine("\t\t/// </summary>");
                                sb.AppendLine("\t\t/// <param name=\"entity\">实体对象</param>");
                                sb.AppendLine("\t\t/// <returns></returns>");
                                sb.AppendLine($"\t\tpublic async Task<int> Delete(string id)");
                                sb.AppendLine("\t\t{");
                                sb.AppendLine("\t\t\ttry");
                                sb.AppendLine("\t\t\t{");
                                sb.AppendLine("\t\t\t\treturn await service.Delete(id);");
                                sb.AppendLine("\t\t\t}");
                                sb.AppendLine("\t\t\tcatch (Exception ex)");
                                sb.AppendLine("\t\t\t{");
                                sb.AppendLine("\t\t\t\tthrow ExceptionEx.Throw(ex);");
                                sb.AppendLine("\t\t\t}");
                                sb.AppendLine("\t\t}");
                                sb.AppendLine();
                            }

                        }
                        break;
                    case "info":
                        {
                            if (item.tableRelationTag == 0)
                            {
                                sb.AppendLine("\t\t/// <summary>");
                                sb.AppendLine("\t\t/// 获取信息");
                                sb.AppendLine("\t\t/// </summary>");
                                sb.AppendLine("\t\t/// <param name=\"id\">主键值</param>");
                                sb.AppendLine("\t\t/// <returns></returns>");
                                sb.AppendLine($"\t\tpublic async Task<{modelTypeName}Entity> GetInfo(string id)");
                                sb.AppendLine("\t\t{");
                                sb.AppendLine("\t\t\ttry");
                                sb.AppendLine("\t\t\t{");
                                sb.AppendLine("\t\t\t\treturn await service.GetInfo(id);");
                                sb.AppendLine("\t\t\t}");
                                sb.AppendLine("\t\t\tcatch (Exception ex)");
                                sb.AppendLine("\t\t\t{");
                                sb.AppendLine("\t\t\t\tthrow ExceptionEx.Throw(ex);");
                                sb.AppendLine("\t\t\t}");
                                sb.AppendLine("\t\t}");
                                sb.AppendLine();
                            }
                            else
                            {
                                sb.AppendLine("\t\t/// <summary>");
                                sb.AppendLine("\t\t/// 获取信息");
                                sb.AppendLine("\t\t/// </summary>");
                                sb.AppendLine("\t\t/// <param name=\"id\">主键值</param>");
                                sb.AppendLine("\t\t/// <returns></returns>");
                                sb.AppendLine($"\t\tpublic async Task<List<{modelTypeName}Entity>> GetInfo(string id)");
                                sb.AppendLine("\t\t{");
                                sb.AppendLine("\t\t\ttry");
                                sb.AppendLine("\t\t\t{");
                                sb.AppendLine("\t\t\t\treturn await service.GetInfo(id);");
                                sb.AppendLine("\t\t\t}");
                                sb.AppendLine("\t\t\tcatch (Exception ex)");
                                sb.AppendLine("\t\t\t{");
                                sb.AppendLine("\t\t\t\tthrow ExceptionEx.Throw(ex);");
                                sb.AppendLine("\t\t\t}");
                                sb.AppendLine("\t\t}");
                                sb.AppendLine();
                            }
                        }
                        break;
                }
            }
            return sb.ToString();
        }

        /// <summary>
        /// 生成IServices层代码文件
        /// </summary>
        /// <param name="modelTypeName"></param>
        /// <param name="keyTypeName"></param>
        /// <param name="ifExistCovered"></param>
        public void GenerateIService(List<CodeGeneratorFuncSwitchModel> funcSwitch, string modelTypeName, bool ifExistCovered = false)
        {
            var iRepositoryPath = Option.OutputPath + Delimiter + "Logic";
            if (!Directory.Exists(iRepositoryPath))
            {
                Directory.CreateDirectory(iRepositoryPath);
            }
            var fullPath = iRepositoryPath + Delimiter + modelTypeName + "IService.cs";
            if (File.Exists(fullPath) && !ifExistCovered)
                return;
            //功能内容
            var funcContent = GenerateIServiceFunction(funcSwitch, modelTypeName);
            var content = ReadTemplate("IServiceTemplate.txt");
            content = content.Replace("{ModelsNamespace}", Option.ModelsNamespace)
                .Replace("{IServicesNamespace}", Option.IServicesNamespace)
                .Replace("{ModelTypeName}", modelTypeName)
                .Replace("{IServiceFunctions}", funcContent);
            WriteAndSave(fullPath, content);
        }

        public string GenerateIServiceFunction(List<CodeGeneratorFuncSwitchModel> funcSwitch, string modelTypeName)
        {
            StringBuilder sb = new StringBuilder();
            foreach (var item in funcSwitch)
            {
                switch (item.funcSwitch)
                {

                    //分页列表
                    case "Page":
                        {
                            if (item.tableRelationTag == 0)
                            {
                                sb.AppendLine("\t\t/// <summary>");
                                sb.AppendLine("\t\t/// 列表(分页)");
                                sb.AppendLine("\t\t/// </summary>");
                                sb.AppendLine("\t\t/// <param name=\"input\">请求参数</param>");
                                sb.AppendLine("\t\t/// <returns></returns>");
                                sb.AppendLine($"\t\tTask<PageResult<{modelTypeName}Entity>> GetPageList({modelTypeName}ListQueryInput input);");
                                sb.AppendLine();
                            }
                        }
                        break;
                    //无分页列表
                    case "noPage":
                        {
                            if (item.tableRelationTag == 0)
                            {
                                sb.AppendLine("\t\t/// <summary>");
                                sb.AppendLine("\t\t/// 列表");
                                sb.AppendLine("\t\t/// </summary>");
                                sb.AppendLine("\t\t/// <returns></returns>");
                                sb.AppendLine($"\t\tTask<List<{modelTypeName}Entity>> GetList({modelTypeName}ListQueryInput input);");
                                sb.AppendLine();
                            }
                        }
                        break;
                    //新建
                    case "add":
                        {
                            if (item.tableRelationTag == 0)
                            {
                                sb.AppendLine("\t\t/// <summary>");
                                sb.AppendLine("\t\t/// 创建");
                                sb.AppendLine("\t\t/// </summary>");
                                sb.AppendLine("\t\t/// <param name=\"entity\">实体对象</param>");
                                sb.AppendLine("\t\t/// <returns></returns>");
                                sb.AppendLine($"\t\tTask<int> Create({modelTypeName}Entity entity);");
                                sb.AppendLine();
                            }
                            else
                            {
                                sb.AppendLine("\t\t/// <summary>");
                                sb.AppendLine("\t\t/// 创建");
                                sb.AppendLine("\t\t/// </summary>");
                                sb.AppendLine("\t\t/// <param name=\"entity\">实体对象</param>");
                                sb.AppendLine("\t\t/// <returns></returns>");
                                sb.AppendLine($"\t\tTask<int> Create({modelTypeName}Entity entity);");
                                sb.AppendLine();
                            }
                        }
                        break;
                    //编辑
                    case "edit":
                        {
                            if (item.tableRelationTag == 0)
                            {
                                sb.AppendLine("\t\t/// <summary>");
                                sb.AppendLine("\t\t/// 更新");
                                sb.AppendLine("\t\t/// </summary>");
                                sb.AppendLine("\t\t/// <param name=\"entity\">实体对象</param>");
                                sb.AppendLine("\t\t/// <returns></returns>");
                                sb.AppendLine($"\t\tTask<int> Update({modelTypeName}Entity entity);");
                                sb.AppendLine();
                            }
                        }
                        break;
                    //删除
                    case "remove":
                        {
                            if (item.tableRelationTag == 0)
                            {
                                sb.AppendLine("\t\t/// <summary>");
                                sb.AppendLine("\t\t/// 删除");
                                sb.AppendLine("\t\t/// </summary>");
                                sb.AppendLine("\t\t/// <param name=\"entity\">实体对象</param>");
                                sb.AppendLine("\t\t/// <returns></returns>");
                                sb.AppendLine($"\t\tTask<int> Delete({modelTypeName}Entity entity);");
                                sb.AppendLine();
                            }
                            else
                            {
                                sb.AppendLine("\t\t/// <summary>");
                                sb.AppendLine("\t\t/// 删除");
                                sb.AppendLine("\t\t/// </summary>");
                                sb.AppendLine("\t\t/// <param name=\"entity\">实体对象</param>");
                                sb.AppendLine("\t\t/// <returns></returns>");
                                sb.AppendLine($"\t\tTask<int> Delete(string id);");
                                sb.AppendLine();
                            }
                        }
                        break;
                    case "info":
                        {
                            if (item.tableRelationTag == 0)
                            {
                                sb.AppendLine("\t\t/// <summary>");
                                sb.AppendLine("\t\t/// 获取信息");
                                sb.AppendLine("\t\t/// </summary>");
                                sb.AppendLine("\t\t/// <param name=\"id\">主键id</param>");
                                sb.AppendLine("\t\t/// <returns></returns>");
                                sb.AppendLine($"\t\tTask<{modelTypeName}Entity> GetInfo(string id);");
                                sb.AppendLine();
                            }
                            else
                            {
                                sb.AppendLine("\t\t/// <summary>");
                                sb.AppendLine("\t\t/// 获取信息");
                                sb.AppendLine("\t\t/// </summary>");
                                sb.AppendLine("\t\t/// <param name=\"id\">主键id</param>");
                                sb.AppendLine("\t\t/// <returns></returns>");
                                sb.AppendLine($"\t\tTask<List<{modelTypeName}Entity>> GetInfo(string id);");
                                sb.AppendLine();
                            }
                        }
                        break;
                }
            }
            return sb.ToString();
        }

        /// <summary>
        /// 生成Service层代码文件
        /// </summary>
        /// <param name="modelTypeName"></param>
        /// <param name="funcSwitch"></param>
        /// <param name="ifExistCovered"></param>
        public void GenerateService(List<CodeGeneratorFuncSwitchModel> funcSwitch, List<DbTableColumn> list, List<GeneratorFormColumn> columnList, DbTable table, string sidx, string sort, bool ifExistCovered = false)
        {
            string modelTypeName = table.Alias;
            var repositoryPath = Option.OutputPath + Delimiter + "Logic";
            if (!Directory.Exists(repositoryPath))
            {
                Directory.CreateDirectory(repositoryPath);
            }
            var fullPath = repositoryPath + Delimiter + modelTypeName + "Service.cs";
            if (File.Exists(fullPath) && !ifExistCovered)
                return;
            //功能内容
            var funcContent = GenerateServiceFunction(funcSwitch, table, list, columnList, sidx, sort);
            var content = ReadTemplate("ServiceTemplate.txt");
            content = content.Replace("{ModelsNamespace}", Option.ModelsNamespace)
                .Replace("{IServicesNamespace}", Option.IServicesNamespace)
                .Replace("{ServicesNamespace}", Option.ServicesNamespace)
                .Replace("{ModelTypeName}", modelTypeName)
                .Replace("{ServiceFunctions}", funcContent);
            WriteAndSave(fullPath, content);
        }

        public string GenerateServiceFunction(List<CodeGeneratorFuncSwitchModel> funcSwitch, DbTable table, List<DbTableColumn> queryList, List<GeneratorFormColumn> columnList, string sidx, string sort)
        {
            string modelTypeName = table.Alias;
            var tableColumns = table.Columns.ToList();
            StringBuilder sb = new StringBuilder();
            foreach (var item in funcSwitch)
            {
                switch (item.funcSwitch)
                {

                    //分页列表
                    case "Page":
                        {
                            if (item.tableRelationTag == 0)
                            {
                                sb.AppendLine("\t\t/// <summary>");
                                sb.AppendLine("\t\t/// 列表（分页）");
                                sb.AppendLine("\t\t/// </summary>");
                                sb.AppendLine("\t\t/// <param name=\"input\">请求参数</param>");
                                sb.AppendLine("\t\t/// <returns></returns>");
                                sb.AppendLine($"\t\tpublic async Task<PageResult<{modelTypeName}Entity>> GetPageList({modelTypeName}ListQueryInput input)");
                                sb.AppendLine("\t\t{");
                                sb.AppendLine("\t\t\tusing (var db = this.Basic)");
                                sb.AppendLine("\t\t\t{");
                                sb.AppendLine($"\t\t\t\tvar queryWhere = ExtLinq.True<{modelTypeName}Entity>();");
                                sb.AppendLine("\t\t\t\tvar queryParam = input.queryJson.ToObject();");
                                foreach (var query in queryList)
                                {
                                    var columnParameter = columnList.Find(f => f.vModel == query.Alias);
                                    var entity = columnParameter.Model;
                                    var input = query.Alias;
                                    sb.AppendLine($"\t\t\t\t//查询{query.Comments}");
                                    switch (query.ColumnType)
                                    {
                                        case "datetime":
                                            sb.AppendLine($"\t\t\t\tif (!string.IsNullOrEmpty(input.{entity}.ToString()))");
                                            break;
                                        case "int":
                                            sb.AppendLine($"\t\t\t\tif (input.{entity}.ToInt()!=0)");
                                            break;
                                        case "decimal":
                                            sb.AppendLine($"\t\t\t\tif (input.{entity}.ToDecimal()>0)");
                                            break;
                                        default:
                                            sb.AppendLine($"\t\t\t\tif (!string.IsNullOrEmpty(input.{entity}))");
                                            break;
                                    }
                                    sb.AppendLine("\t\t\t\t{");
                                    switch (query.ColumnType)
                                    {
                                        case "datetime":
                                            sb.AppendLine($"\t\t\t\t\tqueryWhere = queryWhere.And(m => m.{input} == Convert.ToDateTime(input.{entity}));");
                                            break;
                                        case "int":
                                            sb.AppendLine($"\t\t\t\t\tqueryWhere = queryWhere.And(m => m.{input} == input.{entity});");
                                            break;
                                        case "decimal":
                                            sb.AppendLine($"\t\t\t\tqueryWhere = queryWhere.And(m => m.{input} == input.{entity});");
                                            break;
                                        default:
                                            sb.AppendLine($"\t\t\t\t\tqueryWhere = queryWhere.And(m => m.{input}.Contains(input.{entity}));");
                                            break;
                                    }
                                    sb.AppendLine("\t\t\t\t}");
                                }
                                var defaultSidx = string.Empty;
                                if (!string.IsNullOrEmpty(sidx))
                                {
                                    var sidxEntity = sidx.Replace("F_", "").Replace("f_", "").ToPascalCase();
                                    defaultSidx = sort == "desc" ? $".OrderByDescending(t => t.{sidxEntity})" : $".OrderBy(t => t.{sidxEntity})";
                                }
                                sb.AppendLine($"\t\t\t\treturn await db.GetIQueryable<{modelTypeName}Entity>().Where(queryWhere){defaultSidx}.GetPageResultAsync(input);");
                                sb.AppendLine("\t\t\t}");
                                sb.AppendLine("\t\t}");
                                sb.AppendLine();
                            }
                        }
                        break;
                    //无分页列表
                    case "noPage":
                        {
                            if (item.tableRelationTag == 0)
                            {
                                sb.AppendLine("\t\t/// <summary>");
                                sb.AppendLine("\t\t/// 列表");
                                sb.AppendLine("\t\t/// </summary>");
                                sb.AppendLine("\t\t/// <param name=\"input\">请求参数</param>");
                                sb.AppendLine("\t\t/// <returns></returns>");
                                sb.AppendLine($"\t\tpublic async Task<List<{modelTypeName}Entity>> GetList({modelTypeName}ListQueryInput input)");
                                sb.AppendLine("\t\t{");
                                sb.AppendLine("\t\t\tusing (var db = this.Basic)");
                                sb.AppendLine("\t\t\t{");
                                sb.AppendLine($"\t\t\t\tvar queryWhere = ExtLinq.True<{modelTypeName}Entity>();");
                                foreach (var query in queryList)
                                {
                                    var columnParameter = columnList.Find(f => f.vModel == query.Alias);
                                    var entity = columnParameter.Model;
                                    var input = query.Alias;
                                    sb.AppendLine($"\t\t\t\t//查询{query.Comments}");
                                    switch (query.ColumnType)
                                    {
                                        case "datetime":
                                            sb.AppendLine($"\t\t\t\tif (!string.IsNullOrEmpty(input.{entity}.ToString()))");
                                            break;
                                        case "int":
                                            sb.AppendLine($"\t\t\t\tif (input.{entity}.ToInt()!=0)");
                                            break;
                                        case "decimal":
                                            sb.AppendLine($"\t\t\t\tif (input.{entity}.ToDecimal()>0)");
                                            break;
                                        default:
                                            sb.AppendLine($"\t\t\t\tif (!string.IsNullOrEmpty(input.{entity}))");
                                            break;
                                    }
                                    sb.AppendLine("\t\t\t\t{");
                                    switch (query.ColumnType)
                                    {
                                        case "datetime":
                                            sb.AppendLine($"\t\t\t\t\tqueryWhere = queryWhere.And(m => m.{input} == Convert.ToDateTime(input.{entity}));");
                                            break;
                                        case "int":
                                            sb.AppendLine($"\t\t\t\t\tqueryWhere = queryWhere.And(m => m.{input} == input.{entity});");
                                            break;
                                        case "decimal":
                                            sb.AppendLine($"\t\t\t\tqueryWhere = queryWhere.And(m => m.{input} == input.{entity});");
                                            break;
                                        default:
                                            sb.AppendLine($"\t\t\t\t\tqueryWhere = queryWhere.And(m => m.{input}.Contains(input.{entity}));");
                                            break;
                                    }
                                    sb.AppendLine("\t\t\t\t}");
                                }
                                var defaultSidx = string.Empty;
                                if (!string.IsNullOrEmpty(sidx))
                                {
                                    var sidxEntity = sidx.Replace("F_", "").Replace("f_", "").ToPascalCase();
                                    defaultSidx = sort == "desc" ? $".OrderByDescending(t => t.{sidxEntity})" : $".OrderBy(t => t.{sidxEntity})";
                                }
                                sb.AppendLine($"\t\t\t\treturn await db.GetIQueryable<{modelTypeName}Entity>().Where(queryWhere){defaultSidx}.ToListAsync();");
                                sb.AppendLine("\t\t\t}");
                                sb.AppendLine("\t\t}");
                                sb.AppendLine();
                            }
                        }
                        break;
                    //新建
                    case "add":
                        {
                            sb.AppendLine("\t\t/// <summary>");
                            sb.AppendLine("\t\t/// 创建信息");
                            sb.AppendLine("\t\t/// </summary>");
                            sb.AppendLine("\t\t/// <param name=\"entity\">实体对象</param>");
                            sb.AppendLine("\t\t/// <returns></returns>");
                            sb.AppendLine($"\t\tpublic async Task<int> Create({modelTypeName}Entity entity)");
                            sb.AppendLine("\t\t{");
                            sb.AppendLine("\t\t\tusing (var db = this.Basic)");
                            sb.AppendLine("\t\t\t{");
                            sb.AppendLine("\t\t\t\treturn await db.InsertAsync(entity);");
                            sb.AppendLine("\t\t\t}");
                            sb.AppendLine("\t\t}");
                            sb.AppendLine();
                        }
                        break;
                    //编辑
                    case "edit":
                        {
                            if (item.tableRelationTag == 0)
                            {
                                sb.AppendLine("\t\t/// <summary>");
                                sb.AppendLine("\t\t/// 更新信息");
                                sb.AppendLine("\t\t/// </summary>");
                                sb.AppendLine("\t\t/// <param name=\"entity\">实体对象</param>");
                                sb.AppendLine("\t\t/// <returns></returns>");
                                sb.AppendLine($"\t\tpublic async Task<int> Update({modelTypeName}Entity entity)");
                                sb.AppendLine("\t\t{");
                                sb.AppendLine("\t\t\tusing (var db = this.Basic)");
                                sb.AppendLine("\t\t\t{");
                                sb.AppendLine("\t\t\t\treturn await db.UpdateAsync(entity);");
                                sb.AppendLine("\t\t\t}");
                                sb.AppendLine("\t\t}");
                                sb.AppendLine();
                            }
                        }
                        break;
                    //删除
                    case "remove":
                        {
                            if (item.tableRelationTag == 0)
                            {
                                sb.AppendLine("\t\t/// <summary>");
                                sb.AppendLine("\t\t/// 删除信息");
                                sb.AppendLine("\t\t/// </summary>");
                                sb.AppendLine("\t\t/// <param name=\"entity\">实体对象</param>");
                                sb.AppendLine("\t\t/// <returns></returns>");
                                sb.AppendLine($"\t\tpublic async Task<int> Delete({modelTypeName}Entity entity)");
                                sb.AppendLine("\t\t{");
                                sb.AppendLine("\t\t\tusing (var db = this.Basic)");
                                sb.AppendLine("\t\t\t{");
                                sb.AppendLine("\t\t\t\treturn await db.DeleteAsync(entity);");
                                sb.AppendLine("\t\t\t}");
                                sb.AppendLine("\t\t}");
                                sb.AppendLine();
                            }
                            else
                            {
                                sb.AppendLine("\t\t/// <summary>");
                                sb.AppendLine("\t\t/// 删除信息");
                                sb.AppendLine("\t\t/// </summary>");
                                sb.AppendLine("\t\t/// <param name=\"entity\">实体对象</param>");
                                sb.AppendLine("\t\t/// <returns></returns>");
                                sb.AppendLine("\t\tpublic async Task<int> Delete(string id)");
                                sb.AppendLine("\t\t{");
                                sb.AppendLine("\t\t\tusing (var db = this.Basic)");
                                sb.AppendLine("\t\t\t{");
                                var childPrimaryKey = item.relationField.Replace("F_", "").Replace("f_", "").ToPascalCase();
                                sb.AppendLine($"\t\t\t\treturn await db.DeleteAsync<{modelTypeName}Entity>(m => m.{childPrimaryKey} == id);");
                                sb.AppendLine("\t\t\t}");
                                sb.AppendLine("\t\t}");
                                sb.AppendLine();
                            }
                        }
                        break;
                    case "info":
                        {
                            if (item.tableRelationTag == 0)
                            {
                                sb.AppendLine("\t\t/// <summary>");
                                sb.AppendLine("\t\t/// 获取信息");
                                sb.AppendLine("\t\t/// </summary>");
                                sb.AppendLine("\t\t/// <param name=\"id\">主键id</param>");
                                sb.AppendLine("\t\t/// <returns></returns>");
                                sb.AppendLine($"\t\tpublic async Task<{modelTypeName}Entity> GetInfo(string id)");
                                sb.AppendLine("\t\t{");
                                sb.AppendLine("\t\t\tusing (var db = this.Basic)");
                                sb.AppendLine("\t\t\t{");
                                var columnPrimary = tableColumns.Find(c => c.IsPrimaryKey);
                                sb.AppendLine($"\t\t\t\treturn await db.GetEntityAsync<{modelTypeName}Entity>(m => m.{columnPrimary.Alias} == id);");
                                sb.AppendLine("\t\t\t}");
                                sb.AppendLine("\t\t}");
                                sb.AppendLine();
                            }
                            else
                            {
                                sb.AppendLine("\t\t/// <summary>");
                                sb.AppendLine("\t\t/// 获取信息");
                                sb.AppendLine("\t\t/// </summary>");
                                sb.AppendLine("\t\t/// <param name=\"id\">主键id</param>");
                                sb.AppendLine("\t\t/// <returns></returns>");
                                sb.AppendLine($"\t\tpublic async Task<List<{modelTypeName}Entity>> GetInfo(string id)");
                                sb.AppendLine("\t\t{");
                                sb.AppendLine("\t\t\tusing (var db = this.Basic)");
                                sb.AppendLine("\t\t\t{");
                                var childPrimaryKey = item.relationField.Replace("F_", "").Replace("f_", "").ToPascalCase();
                                sb.AppendLine($"\t\t\t\treturn await db.GetListAsync<{modelTypeName}Entity>(m => m.{childPrimaryKey} == id);");
                                sb.AppendLine("\t\t\t}");
                                sb.AppendLine("\t\t}");
                                sb.AppendLine();
                            }
                        }
                        break;
                }
            }
            return sb.ToString();
        }

        #endregion

        #region 流程代码生成模块

        #region 流程前端

        /// <summary>
        /// 生成流程表单PC端
        /// </summary>
        /// <param name="modelTypeName">下载文件名</param>
        /// <param name="columnPrimary">表主键</param>
        /// <param name="ajaxUrl">请求地址</param>
        /// <param name="formControls">表单控件</param>
        /// <param name="formDataParameter"></param>
        /// <param name="formDataOptions"></param>
        /// <param name="dataInitMethods"></param>
        /// <param name="formTableColumn"></param>
        /// <param name="dataCreated"></param>
        /// <param name="dataMethods"></param>
        /// <param name="formValidation"></param>
        public void GenerateVueFlowForm(string modelTypeName, string columnPrimary, string ajaxUrl, string formControls, string formDataParameter, string formDataOptions, string dataInitMethods, string dataListInitMethods, string formTableColumn, string dataCreated, string dataMethods, string formValidation, List<string> fixedFieldList)
        {
            var repositoryPath = Option.OutputPath + Delimiter + "vue/" + modelTypeName;
            if (!Directory.Exists(repositoryPath))
            {
                Directory.CreateDirectory(repositoryPath);
            }
            var fullPath = repositoryPath + Delimiter + "index.vue";

            //拼接流程表单填充字段
            StringBuilder sb = new StringBuilder();
            var fixedField = string.Empty;
            foreach (var item in fixedFieldList)
            {
                switch (item)
                {
                    case "flowId":
                        sb.AppendLine("\t\t\t\t\tflowId: '',");
                        break;
                    case "status":
                        sb.AppendLine("\t\t\t\t\tstatus:1,");
                        fixedField = "status";
                        break;
                    case "freeApproverUserId":
                        sb.AppendLine("\t\t\t\t\tfreeApproverUserId: '',");
                        break;
                    case "actionType":
                        sb.AppendLine("\t\t\t\t\tactionType:1,");
                        fixedField = "actionType";
                        break;
                }
            }

            var content = ReadTemplate("FlowFormTemplate.txt");
            content = content.Replace("{FormControls}", formControls)
                .Replace("{FormDataParameter}", sb.ToString() + formDataParameter)
                .Replace("{FormDataOptions}", formDataOptions)
                .Replace("{DataInitMethods}", dataInitMethods)
                .Replace("{DataListInitMethods}", dataListInitMethods)
                .Replace("{FormTableColumn}", formTableColumn)
                .Replace("{FormDataCreated}", dataCreated)
                .Replace("{FormDataMethods}", dataMethods)
                .Replace("{FormValidation}", formValidation)
                .Replace("{AjaxUrl}", ajaxUrl)
                .Replace("{FixedField}", fixedField)
                .Replace("{ColumnPrimary}", columnPrimary.ToLower());
            WriteAndSave(fullPath, content);
        }

        #endregion

        #region 流程后端

        /// <summary>
        /// 生成流程api控制器
        /// </summary>
        /// <param name="funcSwitch">API方法</param>
        /// <param name="module">命名空间</param>
        /// <param name="modelTypeName">控制器名称</param>
        /// <param name="list">表单控件</param>
        /// <param name="childTable">表单子表控件</param>
        /// <param name="ifExistCovered">是否覆盖</param>
        public void GenerateApiFlowController(List<CodeGeneratorFuncSwitchModel> funcSwitch, string module, string modelTypeName, string tablePrimary, List<GeneratorFormColumn> list, List<DbTableRelationModel> childTable, bool ifExistCovered = false)
        {
            var controllerPath = Option.OutputPath + Delimiter + "Controllers";
            if (!Directory.Exists(controllerPath))
            {
                Directory.CreateDirectory(controllerPath);
            }
            var fullPath = controllerPath + Delimiter + modelTypeName + "Controller.cs";
            if (File.Exists(fullPath) && !ifExistCovered)
                return;

            var funcContent = GenerateApiFlowControllerFunction(funcSwitch, list, modelTypeName, tablePrimary, childTable);

            var content = ReadTemplate("ApiControllerTemplate.txt");
            content = content.Replace("{ModelsNamespace}", Option.ModelsNamespace)
                .Replace("{ChildService}", "")
                .Replace("{IServicesNamespace}", Option.IServicesNamespace)
                .Replace("{ControllersNamespace}", Option.ControllersNamespace)
                .Replace("{ModelTypeName}", modelTypeName)
                .Replace("{Module}", module)
                .Replace("{ControllerFunctions}", funcContent);
            WriteAndSave(fullPath, content);
        }

        public string GenerateApiFlowControllerFunction(List<CodeGeneratorFuncSwitchModel> funcSwitch, List<GeneratorFormColumn> list, string modelTypeName, string tablePrimary, List<DbTableRelationModel> childTable)
        {
            StringBuilder getSb = new StringBuilder();
            StringBuilder postSb = new StringBuilder();
            StringBuilder sumSb = new StringBuilder();
            foreach (var item in funcSwitch)
            {
                switch (item.funcSwitch)
                {
                    //保存
                    case "save":
                        {
                            postSb.AppendLine("\t\t/// <summary>");
                            postSb.AppendLine("\t\t/// 保存");
                            postSb.AppendLine("\t\t/// </summary>");
                            postSb.AppendLine("\t\t/// <param name=\"input\">请求参数</param>");
                            postSb.AppendLine("\t\t/// <returns></returns>");
                            postSb.AppendLine("\t\t[HttpPost]");
                            postSb.AppendLine($"\t\tpublic async Task<ResponseResult> Save([FromBody] {modelTypeName}CrInput input)");
                            postSb.AppendLine("\t\t{");
                            postSb.AppendLine($"\t\t\tvar deliver = input.MapTo<{modelTypeName}Entity>();");
                            foreach (var column in list)
                            {
                                switch (column.jnpfKey)
                                {
                                    case "checkbox":
                                        postSb.AppendLine($"\t\t\tdeliver.{column.Model} = input.{column.vModel}.ToJson();");
                                        break;
                                    case "select":
                                        if (column.multiple)
                                        {
                                            postSb.AppendLine($"\t\t\tdeliver.{column.Model} = input.{column.vModel}.ToJson();");
                                        }
                                        break;
                                    case "timeRange":
                                        postSb.AppendLine($"\t\t\tdeliver.{column.Model} = input.{column.vModel}.ToJson();");
                                        break;
                                    case "dateRange":
                                        postSb.AppendLine($"\t\t\tdeliver.{column.Model} = input.{column.vModel}.ToJson();");
                                        break;
                                    case "uploadFz":
                                        postSb.AppendLine($"\t\t\tdeliver.{column.Model} = input.{column.vModel}.ToJson();");
                                        break;
                                    case "uploadImg":
                                        postSb.AppendLine($"\t\t\tdeliver.{column.Model} = input.{column.vModel}.ToJson();");
                                        break;
                                    case "slider":
                                        if (column.range)
                                        {
                                            postSb.AppendLine($"\t\t\tdeliver.{column.Model} = input.{column.vModel}.ToJson();");
                                        }
                                        break;
                                    case "address":
                                        postSb.AppendLine($"\t\t\tdeliver.{column.Model} = input.{column.vModel}.ToJson();");
                                        break;
                                }
                            }
                            var childList = new List<string>();
                            if (childTable.Count > 0)
                            {
                                foreach (var items in childTable)
                                {
                                    var tableAliasName = items.table;
                                    var child = Regex.Replace(tableAliasName, @"^.*?_", "");
                                    child = child.Substring(0, 1).ToUpper() + child.Substring(1);
                                    postSb.AppendLine($"\t\t\tvar {child.ToLower()}EntryList = input.{child.ToLower()}.MapToList<{child}Entity>();");
                                    childList.Add($"{child.ToLower()}EntryList");
                                }
                            }
                            var actionType = string.Empty;
                            if (list.Find(c => c.vModel == "status") is null)
                            {
                                actionType = "actionType";
                            }
                            else
                            {
                                actionType = "status";
                            }
                            postSb.AppendLine($"\t\t\tif (input.{actionType} == 1)");
                            postSb.AppendLine("\t\t\t{");
                            postSb.AppendLine($"\t\t\t\tawait {modelTypeName}Service.Save(deliver.{tablePrimary}, deliver{(childList.Count > 0 ? ", " : "")}{string.Join(",", childList.ToArray())});");
                            postSb.AppendLine("\t\t\t\treturn Success(\"保存成功\");");
                            postSb.AppendLine("\t\t\t}");
                            postSb.AppendLine($"\t\t\tawait {modelTypeName}Service.Submit(deliver.{tablePrimary}, deliver{(childList.Count > 0 ? ", " : "")}{string.Join(",", childList.ToArray())});");
                            postSb.AppendLine("\t\t\treturn Success(\"提交成功，请耐心等待\");");
                            postSb.AppendLine("\t\t}");
                            postSb.AppendLine();
                        }
                        break;
                    //提交
                    case "submit":
                        {
                            postSb.AppendLine("\t\t/// <summary>");
                            postSb.AppendLine("\t\t/// 提交");
                            postSb.AppendLine("\t\t/// </summary>");
                            postSb.AppendLine("\t\t/// <param name=\"id\">主键ID</param>");
                            postSb.AppendLine("\t\t/// <param name=\"input\">请求参数</param>");
                            postSb.AppendLine("\t\t/// <returns></returns>");
                            postSb.AppendLine("\t\t[HttpPut(\"{id}\")]");
                            postSb.AppendLine($"\t\tpublic async Task<ResponseResult> Submit(string id, [FromBody] {modelTypeName}UpInput input)");
                            postSb.AppendLine("\t\t{");
                            postSb.AppendLine($"\t\t\tinput.{tablePrimary.ToLower()} = id;");
                            postSb.AppendLine($"\t\t\tvar deliver = input.MapTo<{modelTypeName}Entity>();");
                            foreach (var column in list)
                            {
                                switch (column.jnpfKey)
                                {
                                    case "checkbox":
                                        postSb.AppendLine($"\t\t\tdeliver.{column.Model} = input.{column.vModel}.ToJson();");
                                        break;
                                    case "select":
                                        if (column.multiple)
                                        {
                                            postSb.AppendLine($"\t\t\tdeliver.{column.Model} = input.{column.vModel}.ToJson();");
                                        }
                                        break;
                                    case "timeRange":
                                        postSb.AppendLine($"\t\t\tdeliver.{column.Model} = input.{column.vModel}.ToJson();");
                                        break;
                                    case "dateRange":
                                        postSb.AppendLine($"\t\t\tdeliver.{column.Model} = input.{column.vModel}.ToJson();");
                                        break;
                                    case "uploadFz":
                                        postSb.AppendLine($"\t\t\tdeliver.{column.Model} = input.{column.vModel}.ToJson();");
                                        break;
                                    case "uploadImg":
                                        postSb.AppendLine($"\t\t\tdeliver.{column.Model} = input.{column.vModel}.ToJson();");
                                        break;
                                    case "slider":
                                        if (column.range)
                                        {
                                            postSb.AppendLine($"\t\t\tdeliver.{column.Model} = input.{column.vModel}.ToJson();");
                                        }
                                        break;
                                    case "address":
                                        postSb.AppendLine($"\t\t\tdeliver.{column.Model} = input.{column.vModel}.ToJson();");
                                        break;
                                }
                            }
                            var childList = new List<string>();
                            if (childTable.Count > 0)
                            {
                                foreach (var items in childTable)
                                {
                                    var tableAliasName = items.table;
                                    var child = Regex.Replace(tableAliasName, @"^.*?_", "");
                                    child = child.Substring(0, 1).ToUpper() + child.Substring(1);
                                    postSb.AppendLine($"\t\t\tvar {child.ToLower()}EntryList = input.{child.ToLower()}.MapToList<{child}Entity>();");
                                    childList.Add($"{child.ToLower()}EntryList");
                                }
                            }
                            var actionType = string.Empty;
                            if (list.Find(c => c.vModel == "status") is null)
                            {
                                actionType = "actionType";
                            }
                            else
                            {
                                actionType = "status";
                            }
                            postSb.AppendLine($"\t\t\tif (input.{actionType} == 1)");
                            postSb.AppendLine("\t\t\t{");
                            postSb.AppendLine($"\t\t\t\tawait {modelTypeName}Service.Save(deliver.{tablePrimary}, deliver{(childList.Count > 0 ? ", " : "")}{string.Join(",", childList.ToArray())});");
                            postSb.AppendLine("\t\t\t\treturn Success(\"保存成功\");");
                            postSb.AppendLine("\t\t\t}");
                            postSb.AppendLine($"\t\t\tawait {modelTypeName}Service.Submit(deliver.{tablePrimary}, deliver{(childList.Count > 0 ? ", " : "")}{string.Join(",", childList.ToArray())});");
                            postSb.AppendLine("\t\t\treturn Success(\"提交成功，请耐心等待\");");
                            postSb.AppendLine("\t\t}");
                            postSb.AppendLine();
                        }
                        break;
                    case "info":
                        {
                            getSb.AppendLine("\t\t/// <summary>");
                            getSb.AppendLine("\t\t/// 获取信息");
                            getSb.AppendLine("\t\t/// </summary>");
                            getSb.AppendLine("\t\t/// <param name=\"id\">主键值</param>");
                            getSb.AppendLine("\t\t/// <returns></returns>");
                            getSb.AppendLine("\t\t[HttpGet(\"{id}\")]");
                            getSb.AppendLine("\t\tpublic async Task<ResponseResult> GetInfo(string id)");
                            getSb.AppendLine("\t\t{");
                            getSb.AppendLine($"\t\t\t var output = (await {modelTypeName}Service.GetInfo(id)).MapTo<{modelTypeName}UpOutput>();");
                            if (childTable.Count > 0)
                            {
                                foreach (var items in childTable)
                                {
                                    var tableAliasName = items.table;
                                    var child = Regex.Replace(tableAliasName, @"^.*?_", "");
                                    child = child.Substring(0, 1).ToUpper() + child.Substring(1);
                                    getSb.AppendLine($"\t\t\toutput.{child.ToLower()} = (await {modelTypeName}Service.Get{child}EntryList(id)).MapToList<{child}UpOutput>();");
                                }
                            }
                            getSb.AppendLine("\t\t\treturn Success(output);");
                            getSb.AppendLine("\t\t}");
                            getSb.AppendLine();
                        }
                        break;
                }
            }
            sumSb.AppendLine("\t\t#region GET");
            sumSb.AppendLine();
            sumSb.Append(getSb.ToString());
            sumSb.AppendLine("\t\t#endregion");
            sumSb.AppendLine();
            sumSb.AppendLine("\t\t#region POST");
            sumSb.AppendLine();
            sumSb.Append(postSb.ToString());
            sumSb.AppendLine("\t\t#endregion");
            return sumSb.ToString();
        }

        /// <summary>
        /// 生成Bll层代码文件
        /// </summary>
        /// <param name="modelTypeName"></param>
        /// <param name="ifExistCovered"></param>
        public void GenerateFlowFormBll(List<CodeGeneratorFuncSwitchModel> funcSwitch, DbTable table, List<GeneratorFormColumn> list, List<DbTable> childList, List<DbTableRelationModel> childTable, bool ifExistCovered = false)
        {
            var repositoryPath = Option.OutputPath + Delimiter + "Logic";
            if (!Directory.Exists(repositoryPath))
            {
                Directory.CreateDirectory(repositoryPath);
            }
            var fullPath = repositoryPath + Delimiter + table.Alias + "Bll.cs";
            if (File.Exists(fullPath) && !ifExistCovered)
                return;
            //功能内容
            StringBuilder sb = new StringBuilder();
            sb.AppendLine("\t\tprivate FlowTaskBll flowTaskBll = new FlowTaskBll();");
            sb.AppendLine("\t\tprivate BillRuleBll billRuleService = new BillRuleBll();");
            sb.AppendLine("\t\tprivate FlowEngineBll flowEngineBll = new FlowEngineBll();");

            var funcContent = GenerateFlowFormBllFunction(funcSwitch, table, list, childList, childTable);

            var content = ReadTemplate("RepositoryTemplate.txt");
            content = content.Replace("{ModelsNamespace}", Option.ModelsNamespace)
                .Replace("{RepositoriesNamespace}", Option.RepositoriesNamespace)
                .Replace("{ModelTypeName}", table.Alias)
                .Replace("{ChildService}", sb.ToString())
                .Replace("{BllFunctions}", funcContent);
            WriteAndSave(fullPath, content);
        }

        public string GenerateFlowFormBllFunction(List<CodeGeneratorFuncSwitchModel> funcSwitch, DbTable table, List<GeneratorFormColumn> list, List<DbTable> childTableList, List<DbTableRelationModel> childTable)
        {
            string modelTypeName = table.Alias;
            var tableColumns = table.Columns.ToList();
            var tablePrimary = tableColumns.Find(t => t.IsPrimaryKey);
            var fileJson = tableColumns.Find(t => t.Alias.Contains("FileJson"));
            var billRule = list.Find(f => f.jnpfKey == "billRule");
            StringBuilder sb = new StringBuilder();
            foreach (var item in funcSwitch)
            {
                switch (item.funcSwitch)
                {
                    //详细
                    case "info":
                        {
                            sb.AppendLine("\t\t/// <summary>");
                            sb.AppendLine("\t\t/// 信息");
                            sb.AppendLine("\t\t/// </summary>");
                            sb.AppendLine("\t\t/// <param name=\"input\">请求参数</param>");
                            sb.AppendLine("\t\t/// <returns></returns>");
                            sb.AppendLine($"\t\tpublic async Task<{modelTypeName}Entity> GetInfo(string id)");
                            sb.AppendLine("\t\t{");
                            sb.AppendLine("\t\t\ttry");
                            sb.AppendLine("\t\t\t{");
                            sb.AppendLine("\t\t\t\treturn await service.GetInfo(id);");
                            sb.AppendLine("\t\t\t}");
                            sb.AppendLine("\t\t\tcatch (Exception ex)");
                            sb.AppendLine("\t\t\t{");
                            sb.AppendLine("\t\t\t\tthrow ExceptionEx.Throw(ex);");
                            sb.AppendLine("\t\t\t}");
                            sb.AppendLine("\t\t}");
                            sb.AppendLine();
                        }
                        break;
                    case "child":
                        {
                            foreach (var items in childTable)
                            {
                                var tableAliasName = items.table;
                                var child = Regex.Replace(tableAliasName, @"^.*?_", "");
                                child = child.Substring(0, 1).ToUpper() + child.Substring(1);
                                sb.AppendLine("\t\t/// <summary>");
                                sb.AppendLine("\t\t/// 获取列表");
                                sb.AppendLine("\t\t/// </summary>");
                                sb.AppendLine("\t\t/// <param name=\"input\">请求参数</param>");
                                sb.AppendLine("\t\t/// <returns></returns>");
                                sb.AppendLine($"\t\tpublic async Task<List<{child}Entity>> Get{child}EntryList(string id)");
                                sb.AppendLine("\t\t{");
                                sb.AppendLine("\t\t\ttry");
                                sb.AppendLine("\t\t\t{");
                                sb.AppendLine($"\t\t\t\treturn await service.Get{child}EntryList(id);");
                                sb.AppendLine("\t\t\t}");
                                sb.AppendLine("\t\t\tcatch (Exception ex)");
                                sb.AppendLine("\t\t\t{");
                                sb.AppendLine("\t\t\t\tthrow ExceptionEx.Throw(ex);");
                                sb.AppendLine("\t\t\t}");
                                sb.AppendLine("\t\t}");
                                sb.AppendLine();
                            }
                        }
                        break;
                    //保存
                    case "save":
                        {
                            var childList = new List<string>();
                            sb.AppendLine("\t\t/// <summary>");
                            sb.AppendLine("\t\t/// 保存");
                            sb.AppendLine("\t\t/// </summary>");
                            sb.AppendLine("\t\t/// <param name=\"id\">主键值</param>");
                            sb.AppendLine("\t\t/// <param name=\"entity\">实体对象</param>");
                            foreach (var items in childTable)
                            {
                                var tableAliasName = items.table;
                                var child = Regex.Replace(tableAliasName, @"^.*?_", "");
                                sb.AppendLine($"\t\t/// <param name=\"{child.ToLower()}EntityList\">子表</param>");
                                childList.Add($"List<{child.Substring(0, 1).ToUpper() + child.Substring(1)}Entity> {child}EntityList");
                            }
                            sb.AppendLine("\t\t/// <returns></returns>");
                            sb.AppendLine($"\t\tpublic async Task Save(string id, {modelTypeName}Entity entity{(childTable.Count > 0 ? ", " : "")}{string.Join(",", childList.ToArray())}, int type = 0)");
                            sb.AppendLine("\t\t{");
                            sb.AppendLine("\t\t\ttry");
                            sb.AppendLine("\t\t\t{");
                            //sb.AppendLine("\t\t\t\tusing (TransactionScope scope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))");
                            //sb.AppendLine("\t\t\t\t{");
                            sb.AppendLine("\t\t\t\t\t#region 表单信息");
                            sb.AppendLine("\t\t\t\t\tvar flowEntity = await flowEngineBll.GetInfo(entity.FlowId);");
                            sb.AppendLine("\t\t\t\t\tUserInfo userInfo = UserProvider.Instance.Get();");
                            sb.AppendLine("\t\t\t\t\tstring title = userInfo.UserName + \"的\" + flowEntity.FullName;");
                            sb.AppendLine("\t\t\t\t\tstring billNo = \"单据规则不存在\";");
                            sb.AppendLine("\t\t\t\t\tif (string.IsNullOrEmpty(id))");
                            sb.AppendLine("\t\t\t\t\t{");
                            sb.AppendLine($"\t\t\t\t\t\tentity.{tablePrimary.Alias} = CommonHelper.Guid;");
                            childList = new List<string>();
                            foreach (var items in childTableList)
                            {
                                var tableAliasName = items.TableName;
                                var child = Regex.Replace(tableAliasName, @"^.*?_", "");
                                var childPrimary = items.Columns.ToList().Find(t => t.IsPrimaryKey);
                                var relationChild = childTable.Find(c => c.table == tableAliasName);
                                sb.AppendLine($"\t\t\t\t\t\tforeach (var item in {child}EntityList)");
                                sb.AppendLine("\t\t\t\t\t\t{");
                                sb.AppendLine($"\t\t\t\t\t\t\titem.{childPrimary.Alias} = CommonHelper.Guid;");
                                sb.AppendLine($"\t\t\t\t\t\t\titem.{Regex.Replace(relationChild.tableField, @"^.*?_", "")} = entity.{tablePrimary.Alias};");
                                var sortCode = items.Columns.ToList().Find(f => f.Alias == "SortCode");
                                if (sortCode != null)
                                {
                                    sb.AppendLine($"\t\t\t\t\t\t\titem.SortCode = {child}EntityList.IndexOf(item);");
                                }
                                sb.AppendLine("\t\t\t\t\t\t}");
                                childList.Add($"{child}EntityList");
                            }
                            if (billRule != null)
                            {
                                var columnName = billRule.Model.Substring(0, 1).ToUpper() + billRule.Model.Substring(1);
                                sb.AppendLine($"\t\t\t\t\t\tentity.{columnName} = await billRuleService.GetBillNumber(\"{billRule.billRule}\", false);");
                            }
                            sb.AppendLine($"\t\t\t\t\t\tawait service.Create(entity{(childTable.Count > 0 ? ", " : "")}{string.Join(",", childList.ToArray())});");
                            if (billRule != null)
                            {
                                var columnName = billRule.Model.Substring(0, 1).ToUpper() + billRule.Model.Substring(1);
                                sb.AppendLine($"\t\t\t\t\t\tbillNo = entity.{columnName};");
                            }
                            else
                            {
                                sb.AppendLine($"\t\t\t\t\t\tbillNo = await billRuleService.GetBillNumber(\"{billRule.billRule}\", false);");
                            }
                            if (fileJson != null)
                            {
                                sb.AppendLine("\t\t\t\t\t\tFileManage.CreateFile(JsonHelper.ToList<FileModel>(entity.FileJson));");
                            }
                            sb.AppendLine("\t\t\t\t\t}");
                            sb.AppendLine("\t\t\t\t\telse");
                            sb.AppendLine("\t\t\t\t\t{");
                            sb.AppendLine($"\t\t\t\t\t\tentity.{tablePrimary.Alias} = id;");
                            childList = new List<string>();
                            foreach (var items in childTableList)
                            {
                                var tableAliasName = items.TableName;
                                var child = Regex.Replace(tableAliasName, @"^.*?_", "");
                                var childPrimary = items.Columns.ToList().Find(t => t.IsPrimaryKey);
                                var relationChild = childTable.Find(c => c.table == tableAliasName);
                                sb.AppendLine($"\t\t\t\t\t\tforeach (var item in {child}EntityList)");
                                sb.AppendLine("\t\t\t\t\t\t{");
                                sb.AppendLine($"\t\t\t\t\t\t\titem.{childPrimary.Alias} = CommonHelper.Guid;");
                                sb.AppendLine($"\t\t\t\t\t\t\titem.{Regex.Replace(relationChild.tableField, @"^.*?_", "")} = entity.{tablePrimary.Alias};");
                                var sortCode = items.Columns.ToList().Find(f => f.Alias == "SortCode");
                                if (sortCode != null)
                                {
                                    sb.AppendLine($"\t\t\t\t\t\t\titem.SortCode = {child}EntityList.IndexOf(item);");
                                }
                                sb.AppendLine("\t\t\t\t\t\t}");
                                childList.Add($"{child}EntityList");
                            }
                            sb.AppendLine($"\t\t\t\t\t\tawait service.Update(entity{(childTable.Count > 0 ? ", " : "")}{string.Join(",", childList.ToArray())});");
                            if (fileJson != null)
                            {
                                sb.AppendLine("\t\t\t\t\t\tFileManage.UpdateFile(JsonHelper.ToList<FileModel>(entity.FileJson));");
                            }
                            sb.AppendLine("\t\t\t\t\t}");
                            sb.AppendLine("\t\t\t\t\t#endregion");
                            sb.AppendLine();
                            sb.AppendLine("\t\t\t\t\t#region 流程信息");
                            sb.AppendLine($"\t\t\t\t\tawait flowTaskBll.Save(id, entity.FlowId, entity.{tablePrimary.Alias}, title, 1, billNo, type);");
                            sb.AppendLine("\t\t\t\t\t#endregion");
                            sb.AppendLine();
                            //sb.AppendLine("\t\t\t\t\tscope.Complete();");
                            //sb.AppendLine("\t\t\t\t}");
                            sb.AppendLine("\t\t\t}");
                            sb.AppendLine("\t\t\tcatch (Exception ex)");
                            sb.AppendLine("\t\t\t{");
                            sb.AppendLine("\t\t\t\tthrow ExceptionEx.Throw(ex);");
                            sb.AppendLine("\t\t\t}");
                            sb.AppendLine("\t\t}");
                            sb.AppendLine();
                        }
                        break;
                    //提交
                    case "submit":
                        {
                            var childList = new List<string>();
                            sb.AppendLine("\t\t/// <summary>");
                            sb.AppendLine("\t\t/// 提交");
                            sb.AppendLine("\t\t/// </summary>");
                            sb.AppendLine("\t\t/// <param name=\"id\">主键值</param>");
                            sb.AppendLine("\t\t/// <param name=\"entity\">实体对象</param>");
                            foreach (var items in childTable)
                            {
                                var tableAliasName = items.table;
                                var child = Regex.Replace(tableAliasName, @"^.*?_", "");
                                sb.AppendLine($"\t\t/// <param name=\"{child.ToLower()}EntityList\">子表</param>");
                                childList.Add($"List<{child.Substring(0, 1).ToUpper() + child.Substring(1)}Entity> {child}EntityList");
                            }
                            sb.AppendLine("\t\t/// <returns></returns>");
                            sb.AppendLine($"\t\tpublic async Task Submit(string id, {modelTypeName}Entity entity{(childTable.Count > 0 ? ", " : "")}{string.Join(",", childList.ToArray())})");
                            sb.AppendLine("\t\t{");
                            sb.AppendLine("\t\t\ttry");
                            sb.AppendLine("\t\t\t{");
                            //sb.AppendLine("\t\t\t\tusing (TransactionScope scope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))");
                            //sb.AppendLine("\t\t\t\t{");
                            sb.AppendLine("\t\t\t\t\t#region 表单信息");
                            sb.AppendLine("\t\t\t\t\tvar flowEntity = await flowEngineBll.GetInfo(entity.FlowId);");
                            sb.AppendLine("\t\t\t\t\tUserInfo userInfo = UserProvider.Instance.Get();");
                            sb.AppendLine("\t\t\t\t\tstring title = userInfo.UserName + \"的\" + flowEntity.FullName;");
                            sb.AppendLine("\t\t\t\t\tstring billNo = \"单据规则不存在\";");
                            sb.AppendLine("\t\t\t\t\tif (string.IsNullOrEmpty(id))");
                            sb.AppendLine("\t\t\t\t\t{");
                            sb.AppendLine($"\t\t\t\t\t\tentity.{tablePrimary.Alias} = CommonHelper.Guid;");
                            childList = new List<string>();
                            foreach (var items in childTableList)
                            {
                                var tableAliasName = items.TableName;
                                var child = Regex.Replace(tableAliasName, @"^.*?_", "");
                                var childPrimary = items.Columns.ToList().Find(t => t.IsPrimaryKey);
                                var relationChild = childTable.Find(c => c.table == tableAliasName);
                                sb.AppendLine($"\t\t\t\t\t\tforeach (var item in {child}EntityList)");
                                sb.AppendLine("\t\t\t\t\t\t{");
                                sb.AppendLine($"\t\t\t\t\t\t\titem.{childPrimary.Alias} = CommonHelper.Guid;");
                                sb.AppendLine($"\t\t\t\t\t\t\titem.{Regex.Replace(relationChild.tableField, @"^.*?_", "")} = entity.{tablePrimary.Alias};");
                                var sortCode = items.Columns.ToList().Find(f => f.Alias == "SortCode");
                                if (sortCode != null)
                                {
                                    sb.AppendLine($"\t\t\t\t\t\t\titem.SortCode = {child}EntityList.IndexOf(item);");
                                }
                                sb.AppendLine("\t\t\t\t\t\t}");
                                childList.Add($"{child}EntityList");
                            }
                            if (billRule != null)
                            {
                                var columnName = billRule.Model.Substring(0, 1).ToUpper() + billRule.Model.Substring(1);
                                sb.AppendLine($"\t\t\t\t\t\tentity.{columnName} = await billRuleService.GetBillNumber(\"{billRule.billRule}\", false);");
                            }
                            sb.AppendLine($"\t\t\t\t\t\tawait service.Create(entity{(childTable.Count > 0 ? ", " : "")}{string.Join(",", childList.ToArray())});");
                            if (billRule != null)
                            {
                                var columnName = billRule.Model.Substring(0, 1).ToUpper() + billRule.Model.Substring(1);
                                sb.AppendLine($"\t\t\t\t\t\tbillNo = entity.{columnName};");
                            }
                            else
                            {
                                sb.AppendLine($"\t\t\t\t\t\tbillNo = await billRuleService.GetBillNumber(\"{billRule.billRule}\", false);");
                            }
                            if (fileJson != null)
                            {
                                sb.AppendLine("\t\t\t\t\t\tFileManage.CreateFile(JsonHelper.ToList<FileModel>(entity.FileJson));");
                            }
                            sb.AppendLine("\t\t\t\t\t}");
                            sb.AppendLine("\t\t\t\t\telse");
                            sb.AppendLine("\t\t\t\t\t{");
                            sb.AppendLine($"\t\t\t\t\t\tentity.{tablePrimary.Alias} = id;");
                            childList = new List<string>();
                            foreach (var items in childTableList)
                            {
                                var tableAliasName = items.TableName;
                                var child = Regex.Replace(tableAliasName, @"^.*?_", "");
                                var childPrimary = items.Columns.ToList().Find(t => t.IsPrimaryKey);
                                var relationChild = childTable.Find(c => c.table == tableAliasName);
                                sb.AppendLine($"\t\t\t\t\t\tforeach (var item in {child}EntityList)");
                                sb.AppendLine("\t\t\t\t\t\t{");
                                sb.AppendLine($"\t\t\t\t\t\t\titem.{childPrimary.Alias} = CommonHelper.Guid;");
                                sb.AppendLine($"\t\t\t\t\t\t\titem.{Regex.Replace(relationChild.tableField, @"^.*?_", "")} = entity.{tablePrimary.Alias};");
                                var sortCode = items.Columns.ToList().Find(f => f.Alias == "SortCode");
                                if (sortCode != null)
                                {
                                    sb.AppendLine($"\t\t\t\t\t\t\titem.SortCode = {child}EntityList.IndexOf(item);");
                                }
                                sb.AppendLine("\t\t\t\t\t\t}");
                                childList.Add($"{child}EntityList");
                            }
                            sb.AppendLine($"\t\t\t\t\t\tawait service.Update(entity{(childTable.Count > 0 ? ", " : "")}{string.Join(",", childList.ToArray())});");
                            if (fileJson != null)
                            {
                                sb.AppendLine("\t\t\t\t\t\tFileManage.UpdateFile(JsonHelper.ToList<FileModel>(entity.FileJson));");
                            }
                            sb.AppendLine("\t\t\t\t\t}");
                            sb.AppendLine("\t\t\t\t\t#endregion");
                            sb.AppendLine();
                            sb.AppendLine("\t\t\t\t\t#region 流程信息");
                            sb.AppendLine($"\t\t\t\t\tawait flowTaskBll.Submit(id, entity.FlowId, entity.{tablePrimary.Alias}, title, 1, billNo, entity.MapTo<{modelTypeName}UpInput>());");
                            sb.AppendLine("\t\t\t\t\t#endregion");
                            sb.AppendLine();
                            //sb.AppendLine("\t\t\t\t\tscope.Complete();");
                            //sb.AppendLine("\t\t\t\t}");
                            sb.AppendLine("\t\t\t}");
                            sb.AppendLine("\t\t\tcatch (Exception ex)");
                            sb.AppendLine("\t\t\t{");
                            sb.AppendLine("\t\t\t\tthrow ExceptionEx.Throw(ex);");
                            sb.AppendLine("\t\t\t}");
                            sb.AppendLine("\t\t}");
                            sb.AppendLine();
                            sb.AppendLine("\t\t/// <summary>");
                            sb.AppendLine("\t\t/// 审核修改");
                            sb.AppendLine("\t\t/// </summary>");
                            sb.AppendLine("\t\t/// <param name=\"id\">主键值</param>");
                            sb.AppendLine("\t\t/// <param name=\"obj\">实体对象</param>");
                            sb.AppendLine("\t\tpublic async Task Save(string id, Dictionary<string, object> dic)");
                            sb.AppendLine("\t\t{");
                            sb.AppendLine("\t\t\ttry");
                            sb.AppendLine("\t\t\t{");
                            sb.AppendLine($"\t\t\t\tvar input = dic.ToObject<{modelTypeName}UpInput>();");
                            sb.AppendLine($"\t\t\t\tvar entity = input.MapTo<{modelTypeName}Entity>();");
                            foreach (var items in childTableList)
                            {
                                var tableAliasName = items.TableName;
                                var child = Regex.Replace(tableAliasName, @"^.*?_", "");
                                sb.AppendLine($"\t\t\t\tvar {child}EntityList = input.{child}.MapToList<{child.Substring(0, 1).ToUpper() + child.Substring(1)}Entity>();");
                            }
                            sb.AppendLine($"\t\t\t\tawait this.Save(id, entity{(childTable.Count > 0 ? ", " : "")}{string.Join(",", childList.ToArray())}, 1)");
                            sb.AppendLine("\t\t\t}");
                            sb.AppendLine("\t\t\tcatch (Exception ex)");
                            sb.AppendLine("\t\t\t{");
                            sb.AppendLine("\t\t\t\tthrow new Exception(ex.Message);");
                            sb.AppendLine("\t\t\t}");
                            sb.AppendLine("\t\t}");
                            sb.AppendLine();
                        }
                        break;
                }
            }
            return sb.ToString();
        }

        /// <summary>
        /// 生成IServices层代码文件
        /// </summary>
        /// <param name="modelTypeName"></param>
        /// <param name="keyTypeName"></param>
        /// <param name="ifExistCovered"></param>
        public void GenerateFlowFormIService(List<CodeGeneratorFuncSwitchModel> funcSwitch, string modelTypeName, List<DbTableRelationModel> childTable, bool ifExistCovered = false)
        {
            var iRepositoryPath = Option.OutputPath + Delimiter + "Logic";
            if (!Directory.Exists(iRepositoryPath))
            {
                Directory.CreateDirectory(iRepositoryPath);
            }
            var fullPath = iRepositoryPath + Delimiter + modelTypeName + "IService.cs";
            if (File.Exists(fullPath) && !ifExistCovered)
                return;
            //功能内容
            var funcContent = GenerateFlowFormIServiceFunction(funcSwitch, modelTypeName, childTable);
            var content = ReadTemplate("IServiceTemplate.txt");
            content = content.Replace("{ModelsNamespace}", Option.ModelsNamespace)
                .Replace("{IServicesNamespace}", Option.IServicesNamespace)
                .Replace("{ModelTypeName}", modelTypeName)
                .Replace("{IServiceFunctions}", funcContent);
            WriteAndSave(fullPath, content);
        }

        public string GenerateFlowFormIServiceFunction(List<CodeGeneratorFuncSwitchModel> funcSwitch, string modelTypeName, List<DbTableRelationModel> childTable)
        {
            StringBuilder sb = new StringBuilder();
            foreach (var item in funcSwitch)
            {
                switch (item.funcSwitch)
                {
                    //创建
                    case "create":
                        {
                            var childList = new List<string>();
                            sb.AppendLine("\t\t/// <summary>");
                            sb.AppendLine("\t\t/// 创建");
                            sb.AppendLine("\t\t/// </summary>");
                            sb.AppendLine("\t\t/// <param name=\"entity\">实体对象</param>");
                            foreach (var items in childTable)
                            {
                                var tableAliasName = items.table;
                                var child = Regex.Replace(tableAliasName, @"^.*?_", "");
                                sb.AppendLine($"\t\t/// <param name=\"{child.ToLower()}EntityList\">子表</param>");
                                childList.Add($"List<{child.Substring(0, 1).ToUpper() + child.Substring(1)}Entity> {child}EntityList");
                            }
                            sb.AppendLine("\t\t/// <returns></returns>");
                            sb.AppendLine($"\t\tTask Create({modelTypeName}Entity entity{(childTable.Count > 0 ? ", " : "")}{string.Join(",", childList.ToArray())});");
                            sb.AppendLine();
                        }
                        break;
                    //提交
                    case "update":
                        {
                            var childList = new List<string>();
                            sb.AppendLine("\t\t/// <summary>");
                            sb.AppendLine("\t\t/// 编辑");
                            sb.AppendLine("\t\t/// </summary>");
                            sb.AppendLine("\t\t/// <param name=\"entity\">实体对象</param>");
                            foreach (var items in childTable)
                            {
                                var tableAliasName = items.table;
                                var child = Regex.Replace(tableAliasName, @"^.*?_", "");
                                sb.AppendLine($"\t\t/// <param name=\"{child.ToLower()}EntityList\">子表</param>");
                                childList.Add($"List<{child.Substring(0, 1).ToUpper() + child.Substring(1)}Entity> {child}EntityList");
                            }
                            sb.AppendLine("\t\t/// <returns></returns>");
                            sb.AppendLine($"\t\tTask Update({modelTypeName}Entity entity{(childTable.Count > 0 ? ", " : "")}{string.Join(",", childList.ToArray())});");
                            sb.AppendLine();
                        }
                        break;
                    case "child":
                        {
                            foreach (var items in childTable)
                            {
                                var tableAliasName = items.table;
                                var child = Regex.Replace(tableAliasName, @"^.*?_", "");
                                child = child.Substring(0, 1).ToUpper() + child.Substring(1);
                                sb.AppendLine("\t\t/// <summary>");
                                sb.AppendLine("\t\t/// 获取列表");
                                sb.AppendLine("\t\t/// </summary>");
                                sb.AppendLine("\t\t/// <param name=\"id\">主键值</param>");
                                sb.AppendLine("\t\t/// <returns></returns>");
                                sb.AppendLine($"\t\tTask<List<{child}Entity>> Get{child}EntryList(string id);");
                                sb.AppendLine();
                            }
                        }
                        break;
                    case "info":
                        {
                            sb.AppendLine("\t\t/// <summary>");
                            sb.AppendLine("\t\t/// 获取信息");
                            sb.AppendLine("\t\t/// </summary>");
                            sb.AppendLine("\t\t/// <param name=\"id\">主键id</param>");
                            sb.AppendLine("\t\t/// <returns></returns>");
                            sb.AppendLine($"\t\tTask<{modelTypeName}Entity> GetInfo(string id);");
                            sb.AppendLine();
                        }
                        break;
                }
            }
            return sb.ToString();
        }

        /// <summary>
        /// 生成Service层代码文件
        /// </summary>
        /// <param name="modelTypeName"></param>
        /// <param name="funcSwitch"></param>
        /// <param name="ifExistCovered"></param>
        public void GenerateFlowFormService(List<CodeGeneratorFuncSwitchModel> funcSwitch, DbTable table, List<GeneratorFormColumn> list, List<DbTable> childList, List<DbTableRelationModel> childTable, bool ifExistCovered = false)
        {
            string modelTypeName = table.Alias;
            var repositoryPath = Option.OutputPath + Delimiter + "Logic";
            if (!Directory.Exists(repositoryPath))
            {
                Directory.CreateDirectory(repositoryPath);
            }
            var fullPath = repositoryPath + Delimiter + modelTypeName + "Service.cs";
            if (File.Exists(fullPath) && !ifExistCovered)
                return;
            //功能内容
            var funcContent = GenerateeFlowFormServiceFunction(funcSwitch, table, list, childList, childTable);

            var content = ReadTemplate("ServiceTemplate.txt");
            content = content.Replace("{ModelsNamespace}", Option.ModelsNamespace)
                .Replace("{IServicesNamespace}", Option.IServicesNamespace)
                .Replace("{ServicesNamespace}", Option.ServicesNamespace)
                .Replace("{ModelTypeName}", modelTypeName)
                .Replace("{ServiceFunctions}", funcContent);
            WriteAndSave(fullPath, content);
        }

        public string GenerateeFlowFormServiceFunction(List<CodeGeneratorFuncSwitchModel> funcSwitch, DbTable table, List<GeneratorFormColumn> list, List<DbTable> childTableList, List<DbTableRelationModel> childTable)
        {
            string modelTypeName = table.Alias;
            var tableColumns = table.Columns.ToList();
            var tablePrimary = tableColumns.Find(t => t.IsPrimaryKey);
            StringBuilder sb = new StringBuilder();
            foreach (var item in funcSwitch)
            {
                switch (item.funcSwitch)
                {
                    //创建
                    case "create":
                        {
                            var childList = new List<string>();
                            var childEntity = new List<string>();
                            sb.AppendLine("\t\t/// <summary>");
                            sb.AppendLine("\t\t/// 创建");
                            sb.AppendLine("\t\t/// </summary>");
                            sb.AppendLine("\t\t/// <param name=\"entity\">实体对象</param>");
                            foreach (var items in childTable)
                            {
                                var tableAliasName = items.table;
                                var child = Regex.Replace(tableAliasName, @"^.*?_", "");
                                sb.AppendLine($"\t\t/// <param name=\"{child.ToLower()}EntityList\">子表</param>");
                                childList.Add($"List<{child.Substring(0, 1).ToUpper() + child.Substring(1)}Entity> {child}EntityList");
                                childEntity.Add($"{child}EntityList");
                            }
                            sb.AppendLine("\t\t/// <returns></returns>");
                            sb.AppendLine($"\t\tpublic async Task Create({modelTypeName}Entity entity{(childTable.Count > 0 ? ", " : "")}{string.Join(",", childList.ToArray())})");
                            sb.AppendLine("\t\t{");
                            sb.AppendLine("\t\t\tusing (var db = this.Basic)");
                            sb.AppendLine("\t\t\t{");
                            sb.AppendLine($"\t\t\t\tawait db.InsertAsync(entity);");
                            foreach (var items in childEntity)
                            {
                                sb.AppendLine($"\t\t\t\tawait db.InsertAsync({items});");
                            }
                            sb.AppendLine("\t\t\t}");
                            sb.AppendLine("\t\t}");
                            sb.AppendLine();
                        }
                        break;
                    //编辑
                    case "update":
                        {
                            var childList = new List<string>();
                            var childEntity = new List<string>();
                            sb.AppendLine("\t\t/// <summary>");
                            sb.AppendLine("\t\t/// 编辑");
                            sb.AppendLine("\t\t/// </summary>");
                            sb.AppendLine("\t\t/// <param name=\"entity\">实体对象</param>");
                            foreach (var items in childTable)
                            {
                                var tableAliasName = items.table;
                                var child = Regex.Replace(tableAliasName, @"^.*?_", "");
                                sb.AppendLine($"\t\t/// <param name=\"{child.ToLower()}EntityList\">子表</param>");
                                childList.Add($"List<{child.Substring(0, 1).ToUpper() + child.Substring(1)}Entity> {child}EntityList");
                                childEntity.Add($"{child}EntityList");
                            }
                            sb.AppendLine("\t\t/// <returns></returns>");
                            sb.AppendLine($"\t\tpublic async Task Update({modelTypeName}Entity entity{(childTable.Count > 0 ? ", " : "")}{string.Join(",", childList.ToArray())})");
                            sb.AppendLine("\t\t{");
                            sb.AppendLine("\t\t\tusing (var db = this.Basic)");
                            sb.AppendLine("\t\t\t{");
                            sb.AppendLine($"\t\t\t\tawait db.UpdateAsync(entity);");
                            foreach (var items in childTable)
                            {
                                var tableAliasName = items.table;
                                var child = Regex.Replace(tableAliasName, @"^.*?_", "");
                                child = child.Substring(0, 1).ToUpper() + child.Substring(1);
                                sb.AppendLine($"\t\t\t\tawait db.DeleteAsync<{child}Entity>(m => m.{Regex.Replace(items.tableField, @"^.*?_", "")} == entity.{tablePrimary.Alias});");
                            }
                            foreach (var items in childEntity)
                            {
                                sb.AppendLine($"\t\t\t\tawait db.InsertAsync({items});");
                            }
                            sb.AppendLine("\t\t\t}");
                            sb.AppendLine("\t\t}");
                            sb.AppendLine();
                        }
                        break;
                    case "child":
                        {
                            foreach (var items in childTableList)
                            {
                                var child = items.Alias;
                                sb.AppendLine("\t\t/// <summary>");
                                sb.AppendLine("\t\t/// 获取列表");
                                sb.AppendLine("\t\t/// </summary>");
                                sb.AppendLine("\t\t/// <param name=\"id\">主键值</param>");
                                sb.AppendLine("\t\t/// <returns></returns>");
                                sb.AppendLine($"\t\tpublic async Task<List<{child}Entity>> Get{child}EntryList(string id)");
                                sb.AppendLine("\t\t{");
                                sb.AppendLine("\t\t\tusing (var db = this.Basic)");
                                sb.AppendLine("\t\t\t{");
                                var tableField = childTable.Find(c => c.table == items.TableName);
                                var sortCode = items.Columns.ToList().Find(f => f.Alias == "SortCode");
                                if (sortCode != null)
                                {
                                    sb.AppendLine($"\t\t\t\treturn await db.GetIQueryable<{child}Entity>().Where(m => m.{Regex.Replace(tableField.tableField, @"^.*?_", "")} == id).OrderBy(o => o.SortCode).ToListAsync();");
                                }
                                else
                                {
                                    sb.AppendLine($"\t\t\t\treturn await db.GetIQueryable<{child}Entity>().Where(m => m.{Regex.Replace(tableField.tableField, @"^.*?_", "")} == id).ToListAsync();");
                                }

                                sb.AppendLine("\t\t\t}");
                                sb.AppendLine("\t\t}");
                                sb.AppendLine();
                            }
                        }
                        break;
                    case "info":
                        {
                            sb.AppendLine("\t\t/// <summary>");
                            sb.AppendLine("\t\t/// 信息");
                            sb.AppendLine("\t\t/// </summary>");
                            sb.AppendLine("\t\t/// <param name=\"id\">主键id</param>");
                            sb.AppendLine("\t\t/// <returns></returns>");
                            sb.AppendLine($"\t\tpublic async Task<{modelTypeName}Entity> GetInfo(string id)");
                            sb.AppendLine("\t\t{");
                            sb.AppendLine("\t\t\tusing (var db = this.Basic)");
                            sb.AppendLine("\t\t\t{");
                            sb.AppendLine($"\t\t\t\treturn await db.GetEntityAsync<{modelTypeName}Entity>(m => m.{tablePrimary.Alias} == id);");
                            sb.AppendLine("\t\t\t}");
                            sb.AppendLine("\t\t}");
                            sb.AppendLine();
                        }
                        break;
                }
            }
            return sb.ToString();
        }

        #endregion

        #endregion

        #region App代码生成模块

        /// <summary>
        /// 生成App功能表单Form页面
        /// </summary>
        /// <param name="modelTypeName"></param>
        /// <param name="columnPrimary"></param>
        /// <param name="ajaxUrl"></param>
        /// <param name="formControls"></param>
        /// <param name="formDataParameter"></param>
        public void GenerateVueAppForm(string modelTypeName, string columnPrimary, string ajaxUrl, string formControls, string formDataParameter, string controlsDirectory, string parameterName, string formChildreDataParameter, string formDataOptions)
        {
            var repositoryPath = Option.OutputPath + Delimiter + "vue/" + modelTypeName;
            if (!Directory.Exists(repositoryPath))
            {
                Directory.CreateDirectory(repositoryPath);
            }
            var fullPath = repositoryPath + Delimiter + "Form.vue";
            var content = ReadTemplate("AppFormTemplate.txt");
            content = content.Replace("{FormControls}", formControls)
                .Replace("{FormDataParameter}", formDataParameter)
                .Replace("{FormChildreDataParameter}", formChildreDataParameter)
                .Replace("{FormDataOptions}", formDataOptions)
                .Replace("{ControlsDirectory}", controlsDirectory)
                .Replace("{ParameterName}", parameterName)
                .Replace("{AjaxUrl}", ajaxUrl)
                .Replace("{ColumnPrimary}", columnPrimary.ToLower());
            WriteAndSave(fullPath, content);
        }

        #endregion
    }
}
